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
не подхватывает никаких утечек памяти.