为什么valgrind仅通过多次运行程序就报告不同的结果(不可能泄漏/仍然可以泄漏)?]

问题描述 投票:0回答:1
[在调试随机分段错误时,我运行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作为第一个参数,它总是说]]

仍可到达:4块中1,614字节

考虑到根据this,Valgrind的泄漏报告中的“仍可达到”类别是指仅符合“内存泄漏”的第一个定义的分配。这些块没有被释放,但是它们可以被释放(如果程序员愿意的话),因为程序仍在跟踪指向那些存储块的指针。

嗯,我想释放这些块。谁能告诉我如何?谢谢!

[在调试随机分段错误时,我运行valgrind,多次运行同一程序会得到不同的结果。这是程序的简化版本(我没有得到随机的...

c memory-leaks pthreads valgrind
1个回答
0
投票
我尝试运行您的程序,并且看到了相同的行为。我还发现,删除工作线程中的pthread_exit一行,删除了有关仍可访问内存的valgrind警告。

我开始怀疑glibc,这一点已通过类似的SO问题/答案得到证实:glibc oddity with Valgrind

© www.soinside.com 2019 - 2024. All rights reserved.