2

(私の環境は64ビットUbuntuで、私のアプリケーションはC ++でコンパイルされ、g ++でリンクされています。)

アプリケーションがゼロ除算のようなことをしたりasm("int $3")、コードの左を実行したりすると、次のいずれかがsyslogを介して次のようにログに記録され/var/log/kern.logます/var/log/messages

Sep 10 18:06:47 VM kernel: [117194.123452] a.out[20288] trap divide error ip:45c59d sp:7fff65a91810 error:0 in a.out[400000+144000]
Sep 10 18:07:10 VM kernel: [117217.020833] a.out[20294] trap int3 ip:45c493 sp:7fff5cc559f0 error:0

.mapどちらの場合も、命令ポインタアドレスは、リンク時に作成されたファイルで簡単に検索できるものを指します( " -Wl,-Map,output.map"を使用)。

しかし、セグメンテーション違反を引き起こした場合、この場合memcpy()、ソースをNULLに設定してを呼び出すと、命令ポインターが範囲外になり、どのようにマップされるのかわかりません。

Sep 10 18:06:13 VM kernel: [117160.228587] a.out[20282]: segfault at 0 ip 00007f7e79209092 sp 00007fff831faf08 error 4 in libc-2.9.so[7f7e79185000+168000]

この例では、IPが0x445e70-0x445e7fの範囲にあると予想していました。これは、私の.mapファイルによるとmemcpy()の場所です。

私の質問:この場合のIPを解釈する秘訣は何ですか?

4

1 に答える 1

3

メッセージによると、0x7f7e79185000から始まるプロセスにマップされているmemcpy()からの内部でクラッシュしたようです。これは、ポインタを逆参照しようとしている関数であるlibc-2.9.soため、予想されます。memcpy命令ポインタはlibcの範囲内にあるため、有効に見えます。memcpyをオーバーライドして独自のバージョンを呼び出す場合は、を使用してコンパイルする必要があります-fno-builtin-memcpy

編集: libcを静的にリンクしている可能性がありますが、メッセージによると、libc共有ライブラリもプロセスメモリにマップされています。プログラムの実行中は、 /proc/pidでリストされているはずです。/mapslibstdc ++などの別の共有ライブラリとリンクしている可能性があり、それはlibc共有ライブラリに依存します。その結果、memcpyには2つのバージョンがあり、この場合は、上位アドレスにマップされているlibc共有ライブラリバージョンを呼び出しています。libc共有ライブラリが必要ない場合は、すべてのライブラリを静的にリンクしていることを確認してください。-staticリンク行の先頭にあるオプションを使用します。

于 2009-09-11T04:12:21.943 に答える