Почему valgrind сообщает о разных результатах (утечки невозможны / все еще достижимы), просто запустив программу несколько раз? - PullRequest
0 голосов
/ 23 октября 2019

При отладке ошибки случайной сегментации я запустил valgrind, несколько раз запустив одну и ту же программу, и получил разные результаты. Вот упрощенная версия программы (я не получил случайную ошибку сегментации в этой упрощенной версии):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

pthread_t* tid;
pthread_t prodId;
int numberThreads = 0;

void *worker(void *arg);
void *producer(void *arg);

int main(int argc, char** argv) {
    numberThreads = atoi((char *) argv[1]);
    tid = (pthread_t*) malloc(sizeof (pthread_t) * numberThreads);
    pthread_create(&prodId, NULL, producer, &prodId);
    pthread_join(prodId, NULL);
    free(tid);
    return (EXIT_SUCCESS);
}

void *producer(void *arg) {
    for (int x = 0; x < numberThreads; x++)
        pthread_create(&(tid[x]), NULL, worker, &(tid[x]));
    for (int x = 0; x < numberThreads; x++)
        pthread_join(tid[x], NULL);
    pthread_exit(NULL);
}

void *worker(void *arg) {
    pthread_exit(NULL);
}

Вот результат запуска программы несколько раз подряд:

$ valgrind --leak-check=full --leak-check=full --show-leak-kinds=all  ./memleek 1
==3044== Memcheck, a memory error detector
==3044== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3044== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==3044== Command: ./memleek 1
==3044== 
==3044== 
==3044== HEAP SUMMARY:
==3044==     in use at exit: 0 bytes in 0 blocks
==3044==   total heap usage: 8 allocs, 8 frees, 2,222 bytes allocated
==3044== 
==3044== All heap blocks were freed -- no leaks are possible
==3044== 
==3044== For counts of detected and suppressed errors, rerun with: -v
==3044== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ 
$ 
$ valgrind --leak-check=full --leak-check=full --show-leak-kinds=all  ./memleek 2
==3047== Memcheck, a memory error detector
==3047== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3047== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==3047== Command: ./memleek 2
==3047== 
==3047== 
==3047== HEAP SUMMARY:
==3047==     in use at exit: 0 bytes in 0 blocks
==3047==   total heap usage: 9 allocs, 9 frees, 2,502 bytes allocated
==3047== 
==3047== All heap blocks were freed -- no leaks are possible
==3047== 
==3047== For counts of detected and suppressed errors, rerun with: -v
==3047== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
$
$ valgrind --leak-check=full --leak-check=full --show-leak-kinds=all  ./memleek 2
==3051== Memcheck, a memory error detector
==3051== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3051== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==3051== Command: ./memleek 2
==3051== 
==3051== 
==3051== HEAP SUMMARY:
==3051==     in use at exit: 0 bytes in 0 blocks
==3051==   total heap usage: 9 allocs, 9 frees, 2,502 bytes allocated
==3051== 
==3051== All heap blocks were freed -- no leaks are possible
==3051== 
==3051== For counts of detected and suppressed errors, rerun with: -v
==3051== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
$
$ valgrind --leak-check=full --leak-check=full --show-leak-kinds=all  ./memleek 2
==3055== Memcheck, a memory error detector
==3055== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3055== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==3055== Command: ./memleek 2
==3055== 
==3055== 
==3055== HEAP SUMMARY:
==3055==     in use at exit: 1,614 bytes in 4 blocks
==3055==   total heap usage: 9 allocs, 5 frees, 2,502 bytes allocated
==3055== 
==3055== 36 bytes in 1 blocks are still reachable in loss record 1 of 4
==3055==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==3055==    by 0x401AE89: strdup (strdup.c:42)
==3055==    by 0x4016676: _dl_load_cache_lookup (dl-cache.c:311)
==3055==    by 0x4008A87: _dl_map_object (dl-load.c:2336)
==3055==    by 0x4013B13: dl_open_worker (dl-open.c:237)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x4013608: _dl_open (dl-open.c:660)
==3055==    by 0x517431C: do_dlopen (dl-libc.c:87)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x51743AE: dlerror_run (dl-libc.c:46)
==3055==    by 0x5174421: __libc_dlopen_mode (dl-libc.c:163)
==3055==    by 0x4E4966A: pthread_cancel_init (unwind-forcedunwind.c:52)
==3055== 
==3055== 36 bytes in 1 blocks are still reachable in loss record 2 of 4
==3055==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==3055==    by 0x400B4D3: _dl_new_object (dl-object.c:165)
==3055==    by 0x400587C: _dl_map_object_from_fd (dl-load.c:1000)
==3055==    by 0x400874B: _dl_map_object (dl-load.c:2470)
==3055==    by 0x4013B13: dl_open_worker (dl-open.c:237)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x4013608: _dl_open (dl-open.c:660)
==3055==    by 0x517431C: do_dlopen (dl-libc.c:87)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x51743AE: dlerror_run (dl-libc.c:46)
==3055==    by 0x5174421: __libc_dlopen_mode (dl-libc.c:163)
==3055==    by 0x4E4966A: pthread_cancel_init (unwind-forcedunwind.c:52)
==3055== 
==3055== 360 bytes in 1 blocks are still reachable in loss record 3 of 4
==3055==    at 0x4C2DBC5: calloc (vg_replace_malloc.c:711)
==3055==    by 0x4010FBD: _dl_check_map_versions (dl-version.c:293)
==3055==    by 0x4014076: dl_open_worker (dl-open.c:286)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x4013608: _dl_open (dl-open.c:660)
==3055==    by 0x517431C: do_dlopen (dl-libc.c:87)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x51743AE: dlerror_run (dl-libc.c:46)
==3055==    by 0x5174421: __libc_dlopen_mode (dl-libc.c:163)
==3055==    by 0x4E4966A: pthread_cancel_init (unwind-forcedunwind.c:52)
==3055==    by 0x4E49853: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==3055==    by 0x4E47D7F: __pthread_unwind (unwind.c:121)
==3055== 
==3055== 1,182 bytes in 1 blocks are still reachable in loss record 4 of 4
==3055==    at 0x4C2DBC5: calloc (vg_replace_malloc.c:711)
==3055==    by 0x400B215: _dl_new_object (dl-object.c:75)
==3055==    by 0x400587C: _dl_map_object_from_fd (dl-load.c:1000)
==3055==    by 0x400874B: _dl_map_object (dl-load.c:2470)
==3055==    by 0x4013B13: dl_open_worker (dl-open.c:237)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x4013608: _dl_open (dl-open.c:660)
==3055==    by 0x517431C: do_dlopen (dl-libc.c:87)
==3055==    by 0x400F643: _dl_catch_error (dl-error.c:187)
==3055==    by 0x51743AE: dlerror_run (dl-libc.c:46)
==3055==    by 0x5174421: __libc_dlopen_mode (dl-libc.c:163)
==3055==    by 0x4E4966A: pthread_cancel_init (unwind-forcedunwind.c:52)
==3055== 
==3055== LEAK SUMMARY:
==3055==    definitely lost: 0 bytes in 0 blocks
==3055==    indirectly lost: 0 bytes in 0 blocks
==3055==      possibly lost: 0 bytes in 0 blocks
==3055==    still reachable: 1,614 bytes in 4 blocks
==3055==         suppressed: 0 bytes in 0 blocks
==3055== 
==3055== For counts of detected and suppressed errors, rerun with: -v
==3055== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ 

Я заметил, что если я запускаю 4 рабочих, передавая 4 в качестве первого аргумента, он постоянно говорит:

все еще достижимо: 1 614 байт в 4 блоках

Учитывая, что согласно this категория «все еще достижимая» в отчете об утечке Valgrind относится к выделениям, которые соответствуют только первому определению «утечки памяти». Эти блоки не были освобождены, но они могли быть освобождены (если бы программист захотел), потому что программа все еще отслеживала указатели на эти блоки памяти.

Что ж, я хочу освободить эти блоки. Может кто-нибудь показать мне, как? Спасибо!

1 Ответ

1 голос
/ 23 октября 2019

Я попытался запустить вашу программу и увидел то же самое поведение. Я также обнаружил, что удаление одной строки, pthread_exit в рабочих, убрало предупреждение valgrind о все еще доступной памяти.

Я начал подозревать glibc, и это было подтверждено аналогичным вопросом / ответом SO: странность с Вальгриндом

...