今天调代码发现退出时有内存泄漏,因为有洁癖所以一定要查到原因,最终发现是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)