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;
}

そして、私はこれらの2つの方法でコンパイルしました:

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結合後に呼び出しを追加したときは追加の割り当てがなく、結合前に呼び出しを追加したときは追加の割り当てがあったため、スレッドごとに 1 回限りの割り当てのように見えます。これ_dl_allocate_tlsは通常、動的リンク中に呼び出される関数であることを示唆していますが、スレッドスタックの初期化中に呼び出されているようです。glibcコードをgrep すると、で呼び出されていることがわかりallocate_stack.cます。

_dl_deallocate_tls対応するinの呼び出しがあるようですglibcので、このエラーは無害だと思います。valgrindメモリリークを検出しません。

于 2012-08-27T21:56:55.443 に答える