2016-12-13 3 views
0

私はコア用のgdbセッションを持っていて、そのメンバの1つを読むときにポインタの逆参照にセグメンテーションがあることを示します。ポインタの値はnullではありません。これは、メモリアドレスがプロセスからアクセスできないことを意味すると仮定します。どのようにして、コアのポストモーテムgdbセッションからこの情報を取得できますか?私はGDBでこのプログラムをデバッグする場合どのようにgdbに与えられたアドレスにメモリ特性を教えさせるのですか

#include <iostream> 

using namespace std; 

int 
main(int argc, char* argv[]) 
{ 
    int *ptr = new int(5); 
    cout << "I can access it here: " << *ptr << endl; 

    delete ptr; 

    cout << "But I shouldn't do so here: " << *ptr << endl; 
    return 0; 
} 

$ g++ -g -Wall test.cc -o test 
$ gdb ./test 
(gdb) b 13 
... 
Breakpoint 1 at 0x400943: file test.cc, line 13. 
(gdb) run 
Starting program: /usr/home/nfs/bneradt/test/test 
I can access it here: 5 

Breakpoint 1, main (argc=1, argv=0x7fffffffe348) at test.cc:13 
13   cout << "But I shouldn't do so here: " << *ptr << endl; 
(gdb) 

私はPTRからメモリどのような種類の情報を取得することができます

例えば

は、以下のプログラムを与えられましたか? ptrが解放されたメモリを指していると判断できますか?コアで私は(上記のおもちゃのテストバイナリではない)デバッグしているので、私は、逆参照を持っている - つまり、ポインタを書いていないから、読んで、私は元のメモリ位置がページアウトされたと仮定したプロセスアクセス可能なメモリ? gdbセッションからそれを判別できますか?

+0

[C++ deleteの可能な複製 - オブジェクトを削除しますが、まだデータにアクセスできますか?](http://stackoverflow.com/questions/1930459/c-delete-it-deletes-my-objects-but- i-can-still-access-the-data) – user4581301

+0

C++は、必要なものだけを支払うという哲学に従うので、間違って間違ったテストや時間を無駄にすることはありません。 – user4581301

+0

その投稿は私の質問に答えません。私は解放されたメモリアドレスを読み込むのがクラッシュするかどうかについては問いません。明らかに多くの状況でそうではありません。私は私のポストでそれを認めます。私は、gdbがpostmortemコアのメモリアドレスについて教えてくれるものについて質問しています。 – firebush

答えて

2

gdbには動的割り当ての概念がなく、解放されたメモリについての考えはありません。

gdb> info files 
gdb> maintenance info sections 

が、あなたのプログラムがSIGSEGVでクラッシュしているので、あなたはすでにそれがマップされていないアドレスにアクセスしようとしている知っている:それは、アドレスが、プロセスのアドレス空間にマップされているかどうかを伝えることができます。

他のツールでは解放されたメモリへのアクセスを検出できます。 valgrindは通常友人ですが、死後のデバッグには使用できません。その動作を理解するには、valgrindの下でプログラムを実行する必要があります。

ポインタを参照解除することはめったにありませんが、ポインタが解放されたメモリを指していることを意味します。多くの場合、解放されたメモリに常駐しているポインタ自体が再利用され、上書きされます。したがって

int** ptrarr = new int*[5]; 
ptrarr[3] = new int(5); 
// later 
delete [] ptrarr; 
// later still after many memory allocations 
int* ptr = ptrarr[3]; // ptrarr points to freed memory; UB but no segfault 
         // ptr contains a seemingly random value 
int num = *ptr;  // possible segfault 

この種の情報をインストールされていない実行可能ファイルの死後のダンプから抽出することは非常に困難です。 mallocnewの社内作業に精通していて、内部データ構造を追跡し、自分のアリーナを手作業でマッピングできる必要があります。これは簡単な作業ではありません。保存されているデバッグシンボルを含む標準ライブラリのバージョンを使用すると役立ちます。

静的/大域変数、スタック変数、上記で指し示されたすべての割り当てられたデータ構造、および他の割り当てられたデータ構造のポインタによって指されるすべての割り当てられたデータ構造を含むプログラムのメモリを試してみることができます。理論的にはこのようなツールは可能ですが、死後のダンプから自動的にこれを実行できるツールはありません。

プログラムメモリまたはその一部をマップしておけば、無効なポインタが存在するアドレスに異なるタイプの無関係なオブジェクトが座っているかどうかを調べることができます。そうであれば、2つのオブジェクトのうちの1つが解放された後に不正にアクセスされた解放されたメモリである可能性があります。

+0

'info proc'はライブデバッグでのみ動作し、死後(' core')では動作しません。 –

+0

@EmployedRussianあなたが正しく編集されています。 –

+0

ありがとう、これは非常に役に立ちます。 – firebush

関連する問題