g++ -static вызывает утечку памяти (сообщает mtrace)

Так что у меня странная проблема, я надеюсь, что кто-то может пролить свет на... У меня есть следующий код:

#include <unistd.h>
#include <mcheck.h>
#include <pthread.h>

static void *run(void *args)
{
  sleep(1);
  return NULL;
}

int main()
{
  mtrace();
  pthread_t thread;
  pthread_create(&thread, NULL, run, NULL);
  pthread_join(thread, NULL);

  return 0;
}

И я компилирую, я скомпилировал это двумя способами:

g++ -static program.cpp -lpthread

а также

g++ program.cpp -ltpthread

Когда я смотрю на вывод mtrace (mem.out в моем случае)

Я вижу следующее, когда использую -static вариант, mtrace доклады:

Memory Not freed:
__________________
   Address      Size   Caller
   0x085ac350   0x88   program.cpp:0

Но когда я исключаю -static вариант, mtrace сообщает славное:

No memory leaks.

Так есть какие-нибудь идеи относительно того, что здесь происходит?

1 ответ

Решение

Вот рецепт для воспроизведения этого на моей обычной настольной системе Linux (FC-17):

#include <mcheck.h>
#include <pthread.h>

extern "C" { static void *run(void *) { return 0; } }

int main() {
  mtrace();
  pthread_t thread;
  pthread_create(&thread, 0, run, 0);
  pthread_join(thread, 0);
  return 0;
}

Составлено с g++ -g -static -pthread, Вот как я выполнил это, чтобы получить mtrace ошибка:

$ MALLOC_TRACE=mt.txt mtrace ./a.out mt.txt

Memory not freed:
-----------------
           Address     Size     Caller
0x00000000011a9c90    0x110  at 0x43d7f9

У меня 64-битная система, поэтому размер не совпадает. Когда я разбираю адрес в gdbДает это:

(gdb) disass 0x43d7f9
Dump of assembler code for function _dl_allocate_tls:
   0x000000000043d7c0 <+0>:     mov    %rbx,-0x20(%rsp)
   0x000000000043d7c5 <+5>:     mov    %rbp,-0x18(%rsp)
...
   0x000000000043d7f4 <+52>:    callq  0x428150 <calloc>
   0x000000000043d7f9 <+57>:    test   %rax,%rax
   0x000000000043d7fc <+60>:    je     0x43d8e0 <_dl_allocate_tls+288>
...

Таким образом, похоже, что локальное хранилище было выделено для потока. Это похоже на одноразовое распределение на поток, потому что при добавлении pthread_create Позвонить после объединения, когда был один, когда я добавил его до объединения. _dl_allocate_tls предполагает, что обычно это функция, вызываемая во время динамического связывания, но, кажется, она вызывается во время инициализации стека потоков. Греп через glibc код показывает, что он вызывается в allocate_stack.c,

Кажется, есть соответствующие призывы к _dl_deallocate_tls в glibcпоэтому я считаю эту ошибку безвредной. valgrind не подхватывает никаких утечек памяти.

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