2012-08-27 29 views
3

所以我具有我希望有人能夠闡明一些......我光有下面的代碼一個奇怪的問題: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; 
} 

而且我編譯我編譯它在這2種方式:

g++ -static program.cpp -lpthread 

g++ program.cpp -ltpthread 

當我看着命令mtrace的輸出在我的CAS(mem.out E)

我看到下面當我使用-static選項,mtrace報道:

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

但是,當我排除-static選項,mtrace報告光榮:

No memory leaks. 

所以任何想法至於這裏發生了什麼?

+0

不確定靜態分配的東西可能會在mtrace報告泄漏後釋放靜態分配的東西。我記得_CrtDumpMemoryLeaks()發生了相同的事情; –

+3

'int void main' ?? –

+0

聽起來像mtrace的一個功能,試試Valgrind? –

回答

2

下面是我的正常的桌面上複製本的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表明這通常是在動態鏈接期間調用的函數,但似乎在線程堆棧初始化過程中被調用。 grep通過glibc代碼顯示它在allocate_stack.c中被調用。

glibc似乎有_dl_deallocate_tls相應的電話,所以我認爲這個錯誤是無害的。 valgrind不接收任何內存泄漏。

+0

有趣的是,'valgrind'和'mtrace'看到的情況不同 – Andrew

+0

@Andrew:確實。 – jxh