утечка памяти с самой pthread_cancel () - PullRequest
2 голосов
/ 19 марта 2012

Я создал поток JOINABLE, а затем отменил его в конце программы, например,

rc2 = pthread_attr_init(&attr);
ERR_IF( rc2 != 0 );
rc2 = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
ERR_IF( rc2 != 0 );
rc2 = pthread_create(&destroy_thread, &attr, destroy_expired_sessions, NULL);
ERR_IF( rc2 != 0 );
...
rc2 = pthread_cancel(destroy_thread);
ERR_IF( rc2 != 0 );
rc2 = pthread_join(destroy_thread, &status);
ERR_IF( rc2 != 0 || (int *)status != PTHREAD_CANCELED);

Тем не менее, есть утечка памяти с pthread_cancel (), проанализированная valgrind:

==17583== 28 bytes in 1 blocks are still reachable in loss record 1 of 1
==17583==    at 0x4006878: malloc (in /m/mls/pkg/trees/2008Q3/ix86-Linux-RHEL5/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==17583==    by 0x79FAC1: _dl_map_object_deps (in /lib/ld-2.5.so)
==17583==    by 0x7A4A67: dl_open_worker (in /lib/ld-2.5.so)
==17583==    by 0x7A0DA5: _dl_catch_error (in /lib/ld-2.5.so)
==17583==    by 0x7A43F1: _dl_open (in /lib/ld-2.5.so)
==17583==    by 0x8BF2E1: do_dlopen (in /lib/libc-2.5.so)
==17583==    by 0x7A0DA5: _dl_catch_error (in /lib/ld-2.5.so)
==17583==    by 0x8BF494: __libc_dlopen_mode (in /lib/libc-2.5.so)
==17583==    by 0x9527D6: pthread_cancel_init (in /lib/libpthread-2.5.so)
==17583==    by 0x94EC1B: pthread_cancel (in /lib/libpthread-2.5.so)
==17583==    by 0x80860CF: authDeinit (authAPI.c:1545)
==17583==    by 0x807F280: main (test_sessionList.c:124)
==17583== 
==17583== LEAK SUMMARY:
==17583==    definitely lost: 0 bytes in 0 blocks.
==17583==      possibly lost: 0 bytes in 0 blocks.
==17583==    still reachable: 28 bytes in 1 blocks.
==17583==         suppressed: 0 bytes in 0 blocks.

Кажется, дефект самой функции pthread_cancel ().Похоже, что malloc () немного памяти, но не освободил () позже.Есть ли способ избежать утечки памяти здесь?

Ответы [ 3 ]

3 голосов
/ 19 марта 2012

Так работает pthread_cancel(). При вызове он вызовет pthread_cancel_init(), чтобы убедиться, что несколько элементов динамически связаны (используя эквиваленты dlopen() и dlsym()). Эти динамически связанные функции / символы предназначены быть доступными до конца срока службы процесса.

Так что это не утечка в том смысле, что что-то было потеряно - скорее это что-то загруженное и предназначенное для того, чтобы остаться в живых.

Я бы предложил настроить valgrind на игнорирование этого распределения, если это возможно.

1 голос
/ 19 марта 2012

Тот факт, что ваша утечка памяти обозначена как «достижимая», означает, что вы просто не вызвали free для указателя ... другими словами, указатель все еще является доступным указателем, и он все еще указывает на выделенныйпамять, когда процесс завершается.Указатель не вышел из области видимости, что привело бы к ситуации, когда вы полностью «потеряли» ссылку на память и не можете вызвать free для нее.

Иногда удержание динамического выделения памяти для всего процесса может быть желательной особенностью, например, использование динамической памяти, чтобы избежать статических проблем инициализации, как описано здесь 1006 *.Вы не опубликовали достаточно кода, чтобы на самом деле диагностировать, в чем именно заключается проблема, но я очень сомневаюсь, что проблема связана с самим pthread_cancel, а скорее связана с тем, как вы перемещаете память с помощью указателей в коде, гдекажется, что некоторые из этих указателей не дают утечку памяти, а просто все еще держат память, на которую они указывают, когда процесс завершается.

0 голосов
/ 19 марта 2012

Принудительное завершение потока никогда не является хорошей идеей.Лучше придумать чистый способ сигнализировать потоку о том, что он должен сам выйти (и выполнить очистку своего ресурса).Затем вызовите просто pthread_join, чтобы завершить очистку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...