gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 14:35:29 24 4
gpt4 key购买 nike

在调试随机段错误时,我运行了 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 作为第一个参数,它会不断显示

still reachable: 1,614 bytes in 4 blocks

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

好吧,我想释放这些 block 。谁能告诉我怎么做?谢谢!

最佳答案

我尝试运行你的程序,我看到了同样的行为。我还发现删除一行,即工作线程中的 pthread_exit,删除了有关仍可访问内存的 valgrind 警告。

我开始怀疑 glibc,并且类似的问题/答案证实了这一点: glibc oddity with Valgrind

关于c - 为什么 valgrind 仅通过多次运行程序就报告不同的结果(不可能/仍然可以到达泄漏)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58514595/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com