3

所以我有一个奇怪的问题,我希望有人能解释一下......我有以下代码:

#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.

那么关于这里发生了什么的任何想法?

4

1 回答 1

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_tlsin glibc,所以我认为这个错误是无害的。valgrind不拾取任何内存泄漏。

于 2012-08-27T21:56:55.443 回答