web-dev-qa-db-ja.com

セグメンテーション違反メッセージの解釈

次のセグメンテーション違反メッセージの正しい解釈は何ですか?

segfault at 10 ip 00007f9bebcca90d sp 00007fffb62705f0 error 4 in libQtWebKit.so.4.5.2[7f9beb83a000+f6f000]
segfault at 10 ip 00007fa44d78890d sp 00007fff43f6b720 error 4 in libQtWebKit.so.4.5.2[7fa44d2f8000+f6f000]
segfault at 11 ip 00007f2b0022acee sp 00007fff368ea610 error 4 in libQtWebKit.so.4.5.2[7f2aff9f7000+f6f000]
segfault at 11 ip 00007f24b21adcee sp 00007fff7379ded0 error 4 in libQtWebKit.so.4.5.2[7f24b197a000+f6f000]
53
knorv

これは、実行するコードを見つけようとする(つまり、命令フェッチ中に)NULLポインターを追跡するためのセグメンテーション違反です。

これがプログラムであり、共有ライブラリではない場合

実行addr2line -e yourSegfaultingProgram 00007f9bebcca90d(および指定された他の命令ポインター値についても繰り返して)エラーが発生している場所を確認します。デバッグ用のインストルメントビルドを取得し、gdbなどのデバッガーで問題を再現してください。

共有ライブラリだから

残念ながらあなたはうんざりしています。事後的に動的リンカーによってライブラリがメモリ内のどこに配置されたかを知ることはできません。 gdbの下で問題を再現します。

エラーの意味

フィールドの内訳は次のとおりです。

  • addressatの後)-コードがアクセスしようとしているメモリ内の場所(おそらく10および11は、有効な値に設定されるはずのポインターからのオフセットですが、代わりに0
  • ip-命令ポインター。これをしようとしているコードがどこにあるか
  • sp-スタックポインター
  • error-ページフォルトのエラーコード。これがx86で意味することについては、以下を参照してください。

    /*
     * Page fault error code bits:
     *
     *   bit 0 ==    0: no page found       1: protection fault
     *   bit 1 ==    0: read access         1: write access
     *   bit 2 ==    0: kernel-mode access  1: user-mode access
     *   bit 3 ==                           1: use of reserved bit detected
     *   bit 4 ==                           1: fault was an instruction fetch
     */
    
85
Charles Duffy

エラー4は、「原因はページが見つからないユーザーモードの読み取りである」ことを意味します。それをデコードするツールがあります ここ

これがカーネルの定義です。 4はビット2が設定され、他のビットは設定されないことを意味することに注意してください。バイナリに変換すると、明らかになります。

/*
 * Page fault error code bits
 *      bit 0 == 0 means no page found, 1 means protection fault
 *      bit 1 == 0 means read, 1 means write
 *      bit 2 == 0 means kernel, 1 means user-mode
 *      bit 3 == 1 means use of reserved bit detected
 *      bit 4 == 1 means fault was an instruction fetch
 */
#define PF_PROT         (1<<0)
#define PF_WRITE        (1<<1)
#define PF_USER         (1<<2)
#define PF_RSVD         (1<<3)
#define PF_INSTR        (1<<4)

ここで、「ip 00007f9bebcca90d」は、セグメンテーション違反が発生したときに命令ポインターが0x00007f9bebcca90dにあったことを意味します。

「libQtWebKit.so.4.5.2 [7f9beb83a000 + f6f000]」は次のことを示しています。

  • クラッシュがあったオブジェクト:「libQtWebKit.so.4.5.2」
  • そのオブジェクトのベースアドレス「7f9beb83a000」
  • そのオブジェクトの大きさ: "f6f000"

ベースアドレスを取得してIPから減算すると、そのオブジェクトへのオフセットが取得されます。

0x00007f9bebcca90d - 0x7f9beb83a000 = 0x49090D

次に、その上でaddr2lineを実行できます。

addr2line -e /usr/lib64/qt45/lib/libQtWebKit.so.4.5.2 -fCi 0x49090D
??
??:0

私の場合、インストールは成功しませんでした。インストールしたコピーがあなたのものと同一ではないか、削除されています。

46
Tim

ソースに行きましょう- たとえば2.6.32 。 show_unhandled_signals sysctlが設定されている場合、メッセージはArch/x86/mm/fault.cのshow_signal_msg()関数によって出力されます。

「エラー」はerrnoやシグナル番号ではなく、「ページフォールトエラーコード」です。enumx86_pf_error_codeの定義を参照してください。

「[7fa44d2f8000 + f6f000]」は、クラッシュ時に問題のオブジェクトがマップされた仮想メモリ領域の開始アドレスとサイズです。 「ip」の値はこの領域に収まる必要があります。この情報があれば、gdbで問題のあるコードを簡単に見つけることができます。

10
sendmoreinfo