13

コア ファイルの分析からメモリ リークを分析したいと考えています。

メモリ リークを挿入し、gcore コマンドでコア ファイルを生成するサンプル コードを作成しました。

#include <stdlib.h>
#include <unistd.h>
void fun()
{
  int *ptr = new int(1234);
}
int main()
{
  int i=0;
  while(i++<2500)
  {
    fun();
}
sleep(360);
return 0;
}

プロセス ID を見つける

ayadav@ajay-PC:~$ ps -aef |grep over  
ajay      8735  6016  0 12:57 pts/2    00:00:00 ./over  
ayadav    8739  4659  0 12:57 pts/10   00:00:00 grep over  

生成されたコア

ayadav@ajay-PC:~$ sudo gcore 8735
[sudo] password for ayadav:
0x00007fbb7dda99a0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81      ../sysdeps/unix/syscall-template.S: No such file or directory.
Saved corefile core.8735

以下のようにコアファイルから一般的なパターンを見つけました(スタックオーバーフロー別のスレッドで提案されているように、生成されたコアファイルのみを見て、プロセスのどの部分がメモリの大部分を使用したかを特定する方法はありますか?

ayadav@ajay-PC:~$ hexdump core.6015 | awk '{printf "%s%s%s%s\n%s%s%s%s\n", $5,$4,$3,$2,$9,$8,$7,$6}' | sort | uniq -c | sort -nr | head
6913 0000000000000000  
2503 0000002100000000  
2501 000004d200000000  
786 0000000000007ffc  
464  
125 1ccbc4d000007ffc  
 92 1ca7ead000000000  
 91 0000000200007ffc  
 89 0000000100007ffc  
 80 0000000100000000  

以下の 2 つのアドレスは疑わしいものです

2503 0000002100000000  
2501 000004d200000000  

core ファイルには次の繰り返しパターンがあります

0003560 0000 0000 0021 0000 0000 0000 04d2 0000  
0003570 0000 0000 0000 0000 0000 0000 0000 0000  
0003580 0000 0000 0021 0000 0000 0000 04d2 0000  
0003590 0000 0000 0000 0000 0000 0000 0000 0000  
00035a0 0000 0000 0021 0000 0000 0000 04d2 0000  
00035b0 0000 0000 0000 0000 0000 0000 0000 0000  
00035c0 0000 0000 0021 0000 0000 0000 04d2 0000  
00035d0 0000 0000 0000 0000 0000 0000 0000 0000  
00035e0 0000 0000 0021 0000 0000 0000 04d2 0000  
00035f0 0000 0000 0000 0000 0000 0000 0000 0000  
0003600 0000 0000 0021 0000 0000 0000 04d2 0000  
0003610 0000 0000 0000 0000 0000 0000 0000 0000  
0003620 0000 0000 0021 0000 0000 0000 04d2 0000  
0003630 0000 0000 0000 0000 0000 0000 0000 0000  
0003640 0000 0000 0021 0000 0000 0000 04d2 0000

しかし、gdb info address や x などのコマンドからアクセスする方法がよくわかりません。シンボル情報をバイナリ形式から変換する方法を教えてください。

4

2 に答える 2

12

1 - メモリ リークは、コア ダンプで評価できます。サンプルの C++ の例を取り上げました。

class Base  
{  
public:  
    virtual void fun(){}  
    virtual void xyz(){}  
    virtual void lmv(){}  
    virtual void abc(){}  
};  

class Derived: public Base  
{  
public:  
    void fun(){}  
    void xyz(){}  
    void lmv(){}  
    void abc(){}  
};  

void fun()  
{  
    Base *obj  = new Derived();  
}  
int main()  
{  
    for(int i = 0; i < 2500;i++)
    {
        fun();
    }
    sleep(3600);
    return 0; 
}

2 - gcore コマンドでコアを作成

3 - コア ファイルから繰り返しパターンを検索します。

ayadav@ajay-PC:~$ hexdump core.10639 | awk '{printf "%s%s%s%s\n%s%s%s%s\n", $5,$4,$3,$2,$9,$8,$7,$6}' | sort | uniq -c | sort -nr  | head
   6685 0000000000000000  
   2502 0000002100000000  
   2500 004008d000000000  
    726 0000000000007eff  
    502   
    125 2e4314d000007eff  
     93 006010d000000000  
     81 0000000100007eff  
     80 0000000100000000  
     73 0000000000000001  

0000002100000000004008d000000000 繰り返しパターンです

4 - 各 qword が何であるかを確認します。

(gdb) info symbol ...
(gdb) x ...

例:

(gdb) info symbol 0x4008d000
No symbol matches 0x4008d000.
(gdb) info symbol 0x4008d0
vtable for Derived + 16 in section .rodata of /home/ayadav/virtual

5 - おそらく最も頻繁に発生する vtable は、メモリ リーク、つまり派生 vtable に関連している必要があります。

注: コアダンプ分析は、メモリ リークを見つけるためのベスト プラクティスではないことに同意します。メモリ リークは、valgrind などのさまざまな静的および動的ツールで見つけることができます。

于 2014-12-24T08:08:41.320 に答える
3

プロセスがメモリ リークを引き起こしているのか、コア ダンプを直接見ていないのかを特定する方法はないと思います。実際、メモリリークと呼ばれるものはありません。コードを書くプログラマの意図を知らずにコメントすることはできません。そうは言っても、コア ダンプのサイズを見ればわかります。たとえば、最初の実行後に 1 つ、長時間の実行後に 1 つの複数のダンプを生成できます。サイズに大きな違いがある場合は、何か問題が発生している可能性があると推測できます。ただし、メモリは生産的な目的に使用できます。

実際のメモリ リークの分析と追跡には、memtrack、valgrind などのツールを使用して、malloc と free にラッパーを追加し、各 alloc と free に関する追加情報を提供する必要があります。

アップデート:

16 進解析を探しているので、ここに私が見ることができるものがあります: あなたのすべての行は 16 バイトであり、2 行で繰り返されます。つまり、チャンクは 32 バイトです。0x4D2 は 10 進数で 1234 です。だから、あなたのデータはそこにあります。1 つの alloc チャンクが 32 バイトである可能性があります。「new()」のたびにアドレスをチェックして 16 進数で出力し、比較して 32 バイトのギャップがあるかどうかを確認し、それについて説明します。

于 2014-12-22T09:56:53.413 に答える