LINUX.ORG.RU

Утекает память при завершении потока.


0

0

Всем доброго дня!

Обнаружил, что течет память при завершении потоков:

Далаем вот такой простой тест:
>>>>>>>>
#include <stdio.h>
#include <pthread.h>



void *thread( void* in )
{
        printf( "I'm running thread\n" );
        return NULL;
}


int main( void )
{
        pthread_t       tid, tid2;
        pthread_create( &tid, NULL, &thread, NULL );
        pthread_create( &tid2, NULL, &thread, NULL );

        /* wait until complete */
        pthread_join( tid, NULL );
        pthread_join( tid2, NULL );
        return 0;
}
<<<<<<<<
собранный: gcc test.c -o test -lpthread
и запущеный через valgrind --tool=memcheck  -v --leak-check=yes --show-reachable=yes  --leak-resolution=high

показывает потерю 136 байт (68 на поток). По стеку видно, что 
теряется TLS. 

Кто-нибудь сталкивался с этим? Является ли это багом libc или я не 
так завершаю поток?

libc: 2.3.6(fedora core 5), 2.3.5(ubuntu breezy)
P.S.
Если завершать через pthread_exit - потерей будет существенно больше :(.

>Кто-нибудь сталкивался с этим?
Насколько valgrind коворит это "баг" в libc, но т.к. судя по всему струтура
живет в течении жизни программы, и память ОС освобождает в конце,
это не совсем утечка.
у меня glibc-2.4:

supp: 15 dl_relocate_object
==16980== malloc/free: in use at exit: 272 bytes in 2 blocks.
==16980== malloc/free: 2 allocs, 0 frees, 272 bytes allocated.
==16980== 272 bytes in 2 blocks are possibly lost in loss record 1 of 1
==16980== at 0x4022BE7: calloc (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==16980== by 0x401135F: _dl_allocate_tls (in /lib/ld-2.4.so)
==16980== LEAK SUMMARY:
==16980== definitely lost: 0 bytes in 0 blocks.
==16980== possibly lost: 272 bytes in 2 blocks.
==16980== still reachable: 0 bytes in 0 blocks.
==16980== suppressed: 0 bytes in 0 blocks.


>Является ли это багом libc или я не
>так завершаю поток?

для линукс правильно, для *nix вообще надо установить состояние потока в joinable,
потому что оно не является соотоянием по умолчанию.

fghj ★★★★★
()
Ответ на: комментарий от fghj

Спасибо за информацию.

Если я правильно понимаю, то valgrind считает память после окончания работы программы, таким образом статистика выдаваемая им - вполне окончательная и структуры обязаны быть убраны.

Короче говоря - есть проблема. посмотрим в коде...

jr_A
() автор топика
Ответ на: комментарий от fghj

Странно, в каких это *nix у потока состояние PTHREAD_CREATE_DETACHED по-умолчанию?
По стандарту POSIX у атрибутов потока pthread_attr_t по умолчанию
опредено как раз состояние PTHREAD_CREATE_JOINABLE .
Мне просто интересно, чтобы не "нарваться".

P.S. Сколько ни работал с потоками (начиная с RedHat 7.1 и по RHEL4),
не встречал такой проблемы. Гонял тестовую прогу, создающую потоки и
печатающую из них ID потока часами - такого эффекта не наблюдал.
Может это взаимодействие с valgrind ?

romanSA
()
Ответ на: комментарий от fghj

Интересно, используется ли NPTL.

Если да, то ситуация странная.

Если нет, то сама пококовая библиотека вполне может организовать у себя кэширование (неподходящее слово, но лучше не придумывается) каких-нибудь структур данных, которое конечно же будет выглядеть как memory leak.

anonymous
()
Ответ на: комментарий от anonymous

>Интересно, используется ли NPTL.

да, используется.

fghj ★★★★★
()
Ответ на: комментарий от anonymous

1. Есть у меня смутное ощущение что все потоки создаются JOINABLE, надо
POSIX вкуривать.
2. Да, NPTL используется.
Насчет кеширования - это не логично. Программа работающая долгое время
и создающая потоки, а потом уничтожающая в процессе работы не должна
терять память - иначе она сама себе вредит. Для меня проблема
серьезная, так как софт на котором я это отловил - создает потоки
тысячами в час - примерно 60 - 150k потерь в час, а так как это
демон - для системы могут наступить тяжелые времена в виде нехватки
памяти через месяц работы.

to RomanSA:
Да, в RHEL4 такой проблемы не наблюдается, зато в федоре 5 - 100%
воспроизводится.

IMHO: вообще удручает ситуация с утечками памяти в opensource.
как-то все не слишком гладко там, если брать демоны - то еще можно
жить, но если взять GUI - вешаться охота.

jr_A
() автор топика
Ответ на: комментарий от romanSA

>По стандарту POSIX у атрибутов потока pthread_attr_t по умолчанию
>опредено как раз состояние PTHREAD_CREATE_JOINABLE .

можно ссылку?

>Мне просто интересно, чтобы не "нарваться".

То ли какой-то клон BSD, то ли Солярис.

Сейчас посмотрел ман о pthread_create на FreeBSD там ничего не говорится о состояние joinable, в отличие от мана на linux.

fghj ★★★★★
()
Ответ на: комментарий от jr_A

> Для меня проблема
> серьезная, так как софт на котором я это отловил - создает потоки
> тысячами в час - примерно 60 - 150k потерь в час

память то помечена не как "определенно потерянная", а как предположительно потерянная.

возможно намного облегчит жизнь создание пула потоков.

> вообще удручает ситуация с утечками памяти в opensource.

и чем она может удручать?
вы думаете в не opensource их нет?
Но в opensource ее возможно найти и исправить.

В данном случае valgrind даже сказал где,
если посмотреть в том модуле в glibc только пару раз вызывается calloc,
так что найти и исправить ошибку не является проблемой,
ну или запостите баг в багзилу.

fghj ★★★★★
()
Ответ на: комментарий от fghj

В разделе по pthread_attr_getdetachstate сказано следующее:

The default value of the detachstate attribute shall be PTHREAD_CREATE_JOINABLE.

Вот Вам ссылочка на раздел:
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getdetac...

А вот собственно и на весь стандарт:
http://www.opengroup.org/onlinepubs/009695399/index.html

romanSA
()
Ответ на: комментарий от fghj

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

> возможно намного облегчит жизнь создание пула потоков.

пул потоков есть, там все и теряется, из-за того, что периодически
количество потоков уменьшается для того что бы не занимать систему
бездействующими потоками.

> и чем она может удручать?
> вы думаете в не opensource их нет?
> Но в opensource ее возможно найти и исправить.

closesource вообще не рассматриваем - там и не такое можно словить :-)
У меня личные счеты с memory leak и я очень нервно к подобным ошибкам
отношусь. Потому и удручаюсь, ибо считаю что программа должна работать
хорошо и правильно :-). Работает хорошо, но вот что-бы правильно -
это не всегда(в смысле памяти), но это уже вопросы религии - что
первичней - функциональность или корректность.

> В данном случае valgrind даже сказал где,
> если посмотреть в том модуле в glibc только пару раз вызывается
> calloc,
> так что найти и исправить ошибку не является проблемой,
> ну или запостите баг в багзилу.

исправить можно, чем я сейчас и занимаюсь.
насчет багзиллы - я в самом начале попросил совета: баг это или
кривые ручки. Ответ пока неопределенный... :-(

Предлагаю свернуть дискуссию.

jr_A
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.