Утечка памяти в windows pthread. `pthread_join` не освобождает память

Простой тест:

void testMemoryLeak_PthreadCreateJoin(void)
{
   auto taskFunction = [](void*args) -> void*
   {
      return nullptr;
   };
   pthread_t pth;
   int err = pthread_create(&pth, /*attr*/nullptr, taskFunction, /*args*/nullptr);
   pthread_join(pth, nullptr);
}

void main(void)
{
   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
   testMemoryLeak_PthreadCreateJoin();
   testMemoryLeak_PthreadCreateJoin();
   testMemoryLeak_PthreadCreateJoin();
   testMemoryLeak_PthreadCreateJoin();
}

Здесь сказано:

Поток является выделенным ресурсом, и вы не освободили его перед выходом. Вам следует позвонить pthread_join; это также устранит необходимость в вашем хакерском и неправильном цикле сна.

Возможно, что даже после того, как вы это исправите, valgrind все равно увидит "утечку", поскольку некоторые реализации потоков POSIX (я предполагаю, что вы используете glibc/NPTL) кэшируют и повторно используют ресурсы потоков, а не освобождают их полностью. Я не уверен, работает ли Valgrind вокруг этого или нет.

Но я уже пользуюсь pthread_join, Я использую VS2015 и его анализатор кучи. Может ли проблема быть в pthread моя конкретная реализация? Я использую PAL от Dongsheng Song

Причины утечки памяти:

Detected memory leaks!
Dumping objects ->
{104} normal block at 0x007742C0, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
{101} normal block at 0x00774398, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
{98} normal block at 0x00774038, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
{95} normal block at 0x00774860, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
Object dump complete.

24 байта для каждого pthread. pthread_join() пришлось освободить память, но это не так. Так что я полагаю, что реализация глючит. Пожалуйста, подтвердите или опровергните это.

1 ответ

Если вы хотите отследить точку выделения, см. _CrtSetAllocHook - вы можете установить свой собственный крюк выделения и проверить стек на наличие известных вам блоков, которые будут просочиться. Однако, чтобы это принесло какие-либо преимущества, вам понадобится отладочная версия реализации POSIX, чтобы правильно видеть стек. Затем вы можете попытаться исправить это, чтобы освободить память.

Другие вопросы по тегам