pthread_exit导致的内存泄漏问题
今天调代码发现退出时有内存泄漏,因为有洁癖所以一定要查到原因,最终发现是pthread_exit导致。
网上查到的内容
线程调用的函数里面,否则会导致资源释放不掉。
void* run_thread(void*)
{
pthread_exit((void*)1);
return (void*)1;
}
在调用pthread_exit后会直接退出函数,是不会调用return的。
void deal_thread(void)
{
pthread_exit((void*)1);
}
void* run_thread(void*)
{
deal_thread();
return (void*)1;
}
这种情况下因线程在deal_thread中就释放了,造成返回堆栈没有被释放。
pthread_exit实现是调用pthread_cancel_push。
实际
pthread_exit((void*)1);
与
return (void*)1;
是等效的,这也是此类问题的解决方法,不要调用pthread_exit。
创建多线程情况下,pthread_exit导致的内存泄漏
我今天遇到的问题与上面讲的不同,泄漏发生在创建超过1个线程(在调线程池代码)以上的情况下发生的。
看到下面的vargind输出我一时无法定位泄漏的点。
最终怀疑到pthread库的问题,并通过nm libpthread.so.0 | grep __libc_dlopen_mode,最终确定是由pthread造成的。 |
再逐一排查最终发现是pthread_exit造成,但具体原因还是没有搞明白。
==8624== HEAP SUMMARY:
==8624== in use at exit: 1,646 bytes in 4 blocks
==8624== total heap usage: 3,069 allocs, 3,065 frees, 980,494 bytes allocated
==8624==
==8624== Searching for pointers to 4 not-freed blocks
==8624== Checked 120,000 bytes
==8624==
==8624== 36 bytes in 1 blocks are still reachable in loss record 1 of 4
==8624== at 0x483577F: malloc (vg_replace_malloc.c:299)
==8624== by 0x401AAD9: strdup (strdup.c:42)
==8624== by 0x4016066: _dl_load_cache_lookup (dl-cache.c:317)
==8624== by 0x4008D0A: _dl_map_object (dl-load.c:2332)
==8624== by 0x4012FEA: dl_open_worker (dl-open.c:228)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x4012BB9: _dl_open (dl-open.c:599)
==8624== by 0x49D706C: do_dlopen (dl-libc.c:96)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x49D7BBE: _dl_catch_error (dl-error-skeleton.c:215)
==8624== by 0x49D7146: dlerror_run (dl-libc.c:46)
==8624== by 0x49D71D5: __libc_dlopen_mode (dl-libc.c:195)
==8624==
==8624== 36 bytes in 1 blocks are still reachable in loss record 2 of 4
==8624== at 0x483577F: malloc (vg_replace_malloc.c:299)
==8624== by 0x400B58F: _dl_new_object (dl-object.c:163)
==8624== by 0x4005E47: _dl_map_object_from_fd (dl-load.c:1001)
==8624== by 0x4008A8C: _dl_map_object (dl-load.c:2466)
==8624== by 0x4012FEA: dl_open_worker (dl-open.c:228)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x4012BB9: _dl_open (dl-open.c:599)
==8624== by 0x49D706C: do_dlopen (dl-libc.c:96)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x49D7BBE: _dl_catch_error (dl-error-skeleton.c:215)
==8624== by 0x49D7146: dlerror_run (dl-libc.c:46)
==8624== by 0x49D71D5: __libc_dlopen_mode (dl-libc.c:195)
==8624==
==8624== 384 bytes in 1 blocks are still reachable in loss record 3 of 4
==8624== at 0x4837B65: calloc (vg_replace_malloc.c:752)
==8624== by 0x4010A1F: _dl_check_map_versions (dl-version.c:274)
==8624== by 0x4013095: dl_open_worker (dl-open.c:277)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x4012BB9: _dl_open (dl-open.c:599)
==8624== by 0x49D706C: do_dlopen (dl-libc.c:96)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x49D7BBE: _dl_catch_error (dl-error-skeleton.c:215)
==8624== by 0x49D7146: dlerror_run (dl-libc.c:46)
==8624== by 0x49D71D5: __libc_dlopen_mode (dl-libc.c:195)
==8624== by 0x488FC7A: pthread_cancel_init (unwind-forcedunwind.c:53)
==8624== by 0x488FE93: _Unwind_ForcedUnwind (unwind-forcedunwind.c:127)
==8624==
==8624== 1,190 bytes in 1 blocks are still reachable in loss record 4 of 4
==8624== at 0x4837B65: calloc (vg_replace_malloc.c:752)
==8624== by 0x400B2AD: _dl_new_object (dl-object.c:73)
==8624== by 0x4005E47: _dl_map_object_from_fd (dl-load.c:1001)
==8624== by 0x4008A8C: _dl_map_object (dl-load.c:2466)
==8624== by 0x4012FEA: dl_open_worker (dl-open.c:228)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x4012BB9: _dl_open (dl-open.c:599)
==8624== by 0x49D706C: do_dlopen (dl-libc.c:96)
==8624== by 0x49D7B2E: _dl_catch_exception (dl-error-skeleton.c:196)
==8624== by 0x49D7BBE: _dl_catch_error (dl-error-skeleton.c:215)
==8624== by 0x49D7146: dlerror_run (dl-libc.c:46)
==8624== by 0x49D71D5: __libc_dlopen_mode (dl-libc.c:195)
==8624==
==8624== LEAK SUMMARY:
==8624== definitely lost: 0 bytes in 0 blocks
==8624== indirectly lost: 0 bytes in 0 blocks
==8624== possibly lost: 0 bytes in 0 blocks
==8624== still reachable: 1,646 bytes in 4 blocks
==8624== suppressed: 0 bytes in 0 blocks
==8624==
==8624== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8624== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)