thread, sleep et memory leak

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour, je suis entrain de faire quelques test et paf le truc pas cool, la fuite mémoire. donc voici un code qui reproduit mon problème :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
#include <pthread.h>
 
pthread_t thread;
 
void onExit ( void )
{
    printf ( "exit\n" );
    pthread_cancel ( thread );
    pthread_join ( thread, NULL );
}
 
void * f ( void * a )
{
    sleep ( 2 );
    printf ( "exit thread\n" );
    exit ( 0 );
}
 
int main ( void )
{
    pthread_create ( &thread, NULL, f, NULL );
    atexit ( onExit );
 
    sleep ( 4 );
    return ( 0 );
}

et voici le message de valgrind :

gcc main.c -pthread -g && valgrind --leak-check=full -v ./a.out
==27369== Memcheck, a memory error detector
==27369== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27369== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==27369== Command: ./a.out
==27369==
--27369-- Valgrind options:
--27369--    --leak-check=full
--27369--    -v
--27369-- Contents of /proc/version:
--27369--   Linux version 4.15.0-43-generic (buildd@lgw01-amd64-001) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018
--27369--
--27369-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-avx-avx2-bmi
--27369-- Page sizes: currently 4096, max supported 4096
--27369-- Valgrind library directory: /usr/lib/valgrind
--27369-- Reading syms from /home/psauleau/tmp/a.out
--27369-- Reading syms from /lib/x86_64-linux-gnu/ld-2.27.so
--27369--   Considering /lib/x86_64-linux-gnu/ld-2.27.so ..
--27369--   .. CRC mismatch (computed 1b7c895e wanted 2943108a)
--27369--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.27.so ..
--27369--   .. CRC is valid
--27369-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux
--27369--   Considering /usr/lib/valgrind/memcheck-amd64-linux ..
--27369--   .. CRC mismatch (computed c25f395c wanted 0a9602a8)
--27369--    object doesn't have a symbol table
--27369--    object doesn't have a dynamic symbol table
--27369-- Scheduler: using generic scheduler lock implementation.
--27369-- Reading suppressions file: /usr/lib/valgrind/default.supp
==27369== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-27369-by-psauleau-on-???
==27369== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-27369-by-psauleau-on-???
==27369== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-27369-by-psauleau-on-???
==27369==
==27369== TO CONTROL THIS PROCESS USING vgdb (which you probably
==27369== don't want to do, unless you know exactly what you're doing,
==27369== or are doing some strange experiment):
==27369==   /usr/lib/valgrind/../../bin/vgdb --pid=27369 ...command...
==27369==
==27369== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==27369==   /path/to/gdb ./a.out
==27369== and then give GDB the following command
==27369==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=27369
==27369== --pid is optional if only one valgrind process is running
==27369==
--27369-- REDIR: 0x401f2f0 (ld-linux-x86-64.so.2:strlen) redirected to 0x58060901 (???)
--27369-- REDIR: 0x401f0d0 (ld-linux-x86-64.so.2:index) redirected to 0x5806091b (???)
--27369-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so
--27369--   Considering /usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--27369--   .. CRC mismatch (computed 4b63d83e wanted 670599e6)
--27369--    object doesn't have a symbol table
--27369-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
--27369--   Considering /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--27369--   .. CRC mismatch (computed a4b37bee wanted 8ad4dc94)
--27369--    object doesn't have a symbol table
==27369== WARNING: new redirection conflicts with existing -- ignoring it
--27369--     old: 0x0401f2f0 (strlen              ) R-> (0000.0) 0x58060901 ???
--27369--     new: 0x0401f2f0 (strlen              ) R-> (2007.0) 0x04c32db0 strlen
--27369-- REDIR: 0x401d360 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c33ee0 (strcmp)
--27369-- REDIR: 0x401f830 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c374f0 (mempcpy)
--27369-- Reading syms from /lib/x86_64-linux-gnu/libpthread-2.27.so
--27369--   Considering /usr/lib/debug/.build-id/28/c6aade70b2d40d1f0f3d0a1a0cad1ab816448f.debug ..
--27369--   .. build-id is valid
--27369-- Reading syms from /lib/x86_64-linux-gnu/libc-2.27.so
--27369--   Considering /lib/x86_64-linux-gnu/libc-2.27.so ..
--27369--   .. CRC mismatch (computed b1c74187 wanted 042cc048)
--27369--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.27.so ..
--27369--   .. CRC is valid
--27369-- REDIR: 0x50f9c70 (libc.so.6:memmove) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8d40 (libc.so.6:strncpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9f50 (libc.so.6:strcasecmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8790 (libc.so.6:strcat) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8d70 (libc.so.6:rindex) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50fb7c0 (libc.so.6:rawmemchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9de0 (libc.so.6:mempcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9c10 (libc.so.6:bcmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8d00 (libc.so.6:strncmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8800 (libc.so.6:strcmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9d40 (libc.so.6:memset) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x51170f0 (libc.so.6:wcschr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8ca0 (libc.so.6:strnlen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8870 (libc.so.6:strcspn) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9fa0 (libc.so.6:strncasecmp) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8840 (libc.so.6:strcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50fa0e0 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8da0 (libc.so.6:strpbrk) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f87c0 (libc.so.6:index) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f8c70 (libc.so.6:strlen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x51036c0 (libc.so.6:memrchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9ff0 (libc.so.6:strcasecmp_l) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9be0 (libc.so.6:memchr) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x5117eb0 (libc.so.6:wcslen) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9050 (libc.so.6:strspn) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9f20 (libc.so.6:stpncpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50f9ef0 (libc.so.6:stpcpy) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50fb7f0 (libc.so.6:strchrnul) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x50fa040 (libc.so.6:strncasecmp_l) redirected to 0x4a2a6e0 (_vgnU_ifunc_wrapper)
--27369-- REDIR: 0x51e93c0 (libc.so.6:__strrchr_avx2) redirected to 0x4c32730 (rindex)
--27369-- REDIR: 0x50f5030 (libc.so.6:calloc) redirected to 0x4c31a70 (calloc)
--27369-- REDIR: 0x51e9590 (libc.so.6:__strlen_avx2) redirected to 0x4c32cf0 (strlen)
--27369-- REDIR: 0x50f2070 (libc.so.6:malloc) redirected to 0x4c2faa0 (malloc)
exit thread
--27369-- REDIR: 0x51e9ab0 (libc.so.6:__mempcpy_avx_unaligned_erms) redirected to 0x4c37130 (mempcpy)
exit
--27369-- Reading syms from /lib/x86_64-linux-gnu/libgcc_s.so.1
--27369--    object doesn't have a symbol table
--27369-- REDIR: 0x50f2950 (libc.so.6:free) redirected to 0x4c30cd0 (free)
--27369-- Discarding syms at 0x604fac0-0x606032d in /lib/x86_64-linux-gnu/libgcc_s.so.1 due to munmap()
==27369==
==27369== HEAP SUMMARY:
==27369==     in use at exit: 272 bytes in 1 blocks
==27369==   total heap usage: 7 allocs, 6 frees, 2,990 bytes allocated
==27369==
==27369== Searching for pointers to 1 not-freed blocks
==27369== Checked 8,474,888 bytes
==27369==
==27369== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==27369==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27369==    by 0x40134A6: allocate_dtv (dl-tls.c:286)
==27369==    by 0x40134A6: _dl_allocate_tls (dl-tls.c:530)
==27369==    by 0x4E44227: allocate_stack (allocatestack.c:627)
==27369==    by 0x4E44227: pthread_create@@GLIBC_2.2.5 (pthread_create.c:644)
==27369==    by 0x1088BC: main (main.c:25)
==27369==
==27369== LEAK SUMMARY:
==27369==    definitely lost: 0 bytes in 0 blocks
==27369==    indirectly lost: 0 bytes in 0 blocks
==27369==      possibly lost: 272 bytes in 1 blocks
==27369==    still reachable: 0 bytes in 0 blocks
==27369==         suppressed: 0 bytes in 0 blocks
==27369==
==27369== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==27369== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Ma question (pour ceux qui sont encore là), est ce que valgrind dit de la me… car il ne vois pas que la memoire est liberé ou est-ce que j’ai loupé un truc ?

Sinon je sais bien qu’un thread devrait pas faire un exit ( 0 ), mais là, le concept de ce thread c’est un watchdog, dans son cas d’utilisation, il doit pouvoir tuer son programme parent si celui est bloqué dans une tâche.

Et puis de toutes façon maintenant que j’ai trouvé ce problème, je vais pouvoir l’oublier :lol:.

+0 -0

Salut,

Ce n’est qu’une hypothèse, mais à mon avis la sortie que tu obtiens viens du fait que ton second thread (celui exécutant la fonction f()) appelle la fonction exit(). De ce fait, tu provoques la fin du programme (et, conséquemment, celle de tous les threads le composant) alors qu’il y a deux threads actifs (fonction f() et fonction main()). Valgrind doit interpréter cela comme une fuite possible car tu stoppes l’exécution du programme sans avoir explicitement libéré les ressources du second thread.

Ceci étant dit, clairement, il n’y a pas de fuites de mémoires dans l’exemple que tu donnes.

Édité par Taurre

+0 -0

Cette réponse a aidé l’auteur du sujet

Je ne vois pas de fuite mémoire, en revanche je vois une deadlock, d’où le "possibly lost" pour des variables globales je pense…

Ta fonction onExit() sera appelée dans le thread de f() et non dans le main(), ce qui fait que le thread va essayer de s’auto-cancel et de s’auto-join (d’après la doc pthread_join devrait te retourner l’erreur EDEADLK d’ailleurs).

Nouveauté C++17 : les décompositions | Nouveautés du C++14 | FYS : une bibliothèque C++ dans le domaine public

+2 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte