3

機能だけに注目しましょうRect_IsEmpty()

コマンドを実行すると、次のnm出力が得られます。

(...)    
00021af0 T Rect_IsEmpty
(...)

一方、gdbこの関数のアドレスを起動して見ると、次のようになります。

(gdb) info address Rect_IsEmpty
Symbol "Rect_IsEmpty" is at 0x8057c84 in a file compiled without debugging.

これらのアドレスが同じではない理由を誰か説明してくれませんか? gdb はこのアドレスをどこから取得しますか?

4

2 に答える 2

10

nmgdbプロセスを実行するたびに変更される実際の仮想プロセスのメモリアドレスを提供しながら、マングルされた名前シンボルテーブルのアドレスオフセットを提供します。

nmは、コード セグメントの先頭からのオフセットを示す単なるツールです。あなたの場合:

00021af0 T Rect_IsEmpty

単に、コード セグメント全体で、他のすべての関数の中で、コード セグメントからのRect_IsEmptyオフセット00021af0があるため、コード セグメントのベースが に再配置された00000000場合、オフセットはアドレスと同じになることを意味します00021af0

Linux で実行可能ファイルを実行する前に、アドレスのランダム化に ASLR メカニズムが使用されますが、すべてのアドレスではなく、セグメントの先頭のみが使用されます。したがって、実行可能ファイルを実行する前に動的シンボルが持つアドレスを常に知ったり依存したりできるとは限りません。セグメントの開始アドレスからのオフセットしか持つことができません。

デバッガーを使用して関数のアドレスを検索すると、ASLR が既にジョブを実行した後で、プロセスのコード セグメント内にシンボルのアドレスが表示されます。

これは、共有ライブラリに関する IBM の優れた記事と、Procedure Linkage Table および Global Offset Table に関する別の記事です。

于 2015-07-08T13:20:51.600 に答える
2

実行可能ファイルは異なるメモリ位置で開始されるため、実行可能ファイル内の割り当てが異なります。したがって、すべての関数は、以前の実行とは異なるメモリ アドレスを持ちます。

あなたの質問に関して、GDBはデバッグ情報からアドレスを取得します-絶対メモリアドレスが表示されます。

于 2015-07-08T13:24:47.250 に答える