g ++ -static导致内存泄漏(由mtrace报告)

时间:2012-08-27 16:16:19

标签: c++ memory-leaks g++ static-libraries 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 个答案:

答案 0 :(得分: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表明这通常是在动态链接期间调用的函数,但似乎在线程堆栈初始化期间调用它。 glibc代码中的grep显示正在allocate_stack.c中调用它。

_dl_deallocate_tls中似乎有glibc的相应调用,所以我认为这个错误是无害的。 valgrind没有发现任何内存泄漏。