
私はデバッグにコアダンプを使用しています。 gdbでは、コアダンプだけでなく実行可能ファイルも提供する必要があります。なぜこれですか?コアダンプにプロセスで使用されるすべてのメモリが含まれている場合、コアダンプに実行可能ファイルが含まれていますか?完全なexeがメモリにロードされるという保証がない場合(単一の実行ファイルは通常それほど大きくありません)、最終的にコアダンプに関連するメモリがすべて含まれていない可能性があります。シンボルに関するものですか(おそらくメモリに正しくロードされていない可能性があります)?
答え1
コアダンプはプログラムのメモリスペースをダンプしたものに過ぎず、すべてがどこにあるのか知っていればそれを使うことができます。
実行可能ファイルを使用する理由は、メモリ(つまりコアファイル)の場所(論理アドレスの側面)を説明するためです。
このコマンドを使用すると、objdump
調査中の実行可能オブジェクトのメタデータがダンプされます。 a.outという実行可能オブジェクトを例に挙げてみましょう。
objdump -h a.out
ヘッダー情報のみをダンプするには、次のセクションが表示されます。。データまたは.bssまたは。テキスト(もっとあります)。これは、オブジェクト内のさまざまな部分を見つけることができる場所、プロセスアドレス空間でロードする必要がある場所、特定の部分(たとえば、.data .text)に対してロードする必要がある場所をカーネルローダーに通知します。 (.bssセクションには、ファイル内のデータは含まれていませんが、初期化されていないデータのためにプロセスによって予約されたメモリ量を表し、ゼロで埋められます。)
実行可能オブジェクトファイルのレイアウトは標準ELFに従います。
objdump -x a.out
- すべてを捨てる
実行可能オブジェクトにまだシンボルテーブルが含まれている場合(削除されておらず、ACソースのコンパイルを想定してデバッグビルドを作成するman strip
ために使用されている場合)、たとえば変数がある場合は、シンボル名で重要な内容を確認できます。 /バッファ名は次のとおりです。-g
gcc
入力ラインソースコードでこの名前を使用してコンテンツgdb
を表示できます。つまり、gdb
プログラム初期化データセグメントからのオフセットを知っています。入力ラインこの変数の開始と長さです。
追加読書第1条、 第2条、実用的な内容はもちろんです。実行可能および接続形式(ELF)仕様。
以下の@mirabilosコメント以降に更新されました。
しかし、以下のようにシンボルテーブルを使用すると、
$ gdb --batch -s a.out -c core -q -ex "x buf1"
生産
0x601060 <buf1>: 0x72617453
すると、シンボルテーブルを使わずにアドレスを直接確認せず、
$ gdb --batch -c core -q -ex "x 0x601060"
生産
0x601060: 0x72617453
2番目のコマンドでは、シンボルテーブルを使用せずに直接メモリを確認しました。
また、@user580082の回答に追加の説明が追加され、投票することがわかります。
答え2
コアファイルは、プロセスが終了したときのスタックイメージ、メモリマップ、およびレジスタのスナップショットです。その内容は与えられた方法で操作することができますコアマニュアルページ。デフォルトでは、プライベートマッピング、共有マッピング、およびELFヘッダー情報はコアファイルにダンプされます。
あなたの質問に答える、gdbに実行ファイルが必要なのは、valgrindのようなバイナリ命令を読み、解釈して実行をシミュレートするのではなく、プロセスの親プロセスとなり、実行時のプロセスの動作を制御するからです。これは、コアファイルを使用して、競合中のプロセスのメモリマップとプロセッサの状態を決定します。
Linuxでは、親プロセスは子プロセスに関する追加情報、特にptrace機能を取得できます。これにより、デバッガはプロセスに関する下位レベルの情報(メモリの読み取り/書き込み、レジスタの変更、信号マップの変更、停止など)にアクセスできます。その実行など
デバッガの仕組みを読んだ後、より多くのコアファイルがありますが、実行可能ファイルの要件を理解することができます。
答え3
(他の良い答えに加えて)
最新のLinux(および多くのUnixのような)システムでは、デバッグ情報(シンボルタイプ、ソースコードの場所、変数タイプなどのメタデータを含む)があります。小人形式で位置非常に低い周波数実行可能ファイル(またはELF共有ライブラリ)は、特定のオプションを使用してコンパイルされます-g
。デバッグしたいプログラムをコンパイルすることをお勧めします-g3 -O0
。おそらく-fno-inline
最近のバージョンを使用している場合でしょう。湾岸協力協議会-O2 -g1
;ただし、GCCを使用すると、最適化およびデバッグ情報を使用してコンパイルすることもできます。ハイゼンベルク)。
この情報を入力しないことは非常に賢明です。核兵器core
同じ実行ファイルがさまざまなコアファイルを持つことができるためです(多くのユーザーがエラーレポートを作成し、ほとんどはダンプを作成するための一般的なソフトウェアを想像してみてください)。返品コア(5)ファイルはカーネルによってダンプされ、カーネルはDWARFセクションの存在を気にしないでください。エルフ(5)実行可能です(これらの部分はマッピングされていないため仮想アドレス空間不完全プロセスコアをどこかに捨てる信号(7))。デバッグ情報を入れることもできます。分離ファイル(実行ファイルを除く)。
ところで、GDBは可能です苦しいデバッグ情報なしで実行可能ファイルをデバッグするためのコアダンプ。しかし、実際には、プログラミング言語とそのコンパイラが提供するシンボルレベルではなく、機械語コードレベルでデバッグしています。
答え4
実行ファイルは実行中に書き込み禁止になっているため、実行中のプロセスではそのファイルを変更できません。さらに、複数のプロセスが同じイメージを実行する場合、コードページ(および定数)はほとんど一度にメモリにロードする必要があります。単一のプロセスがイメージを実行しても、すべてのページをRAMにロードするわけではありません(ページング要求)。ただし、実行可能ファイルの一部(デバッグ情報など)はRAMにまったくロードする必要はありません。
これらすべての理由から意味があります。いいえ各コアダンプファイルに実行可能ファイルをコピーします。これはとにかく「共通要素」です。
したがって、コード(たとえばdisassemble
)を表示するにはgdb
コードページが必要です。理論的には、コアダンプに要求ページングコードのみが含まれている場合は、失敗したプログラム部分を一覧表示でき、呼び出しコードページも「呼び出し」になっている可能性があるため、その部分のみを確認できます。プログラムが失敗しました。
gdb
コードアドレスをソースファイル、行、および変数名に関連付けるには、デバッグシンボル(存在する場合)も必要です。
最後に、動的ライブラリを使用するときは、コアダンプにはすべてのライブラリも含める必要があります。