因此,我遇到了一个奇怪的问题,希望有人能对此有所了解...我有以下代码:

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

那么关于这里发生的事情有什么想法吗?

最佳答案

这是在我的常规台式机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不会占用任何内存泄漏。

关于c++ - g++ -static导致内存泄漏(由mtrace报告),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12145662/

10-09 06:39