1

アプリケーションにコアダンプがあり、分析しようとすると、corrupスタックがあるようです。誰かが問題の根本に到達する方法を教えてもらえますか?

Program terminated with signal 11, Segmentation fault.
#0  0x40173f54 in nanosleep () from /lib/libc.so.6
(gdb) bt
#0  0x40173f54 in nanosleep () from /lib/libc.so.6
#1  0x401b2a1c in __libc_enable_asynccancel () from /lib/libc.so.6
#2  0x0000cdb8 in ?? ()
Cannot access memory at address 0x12



(gdb) info frame
Stack level 0, frame at 0xbeaedbc0:
 pc = 0x40173f54 in nanosleep; saved pc 0x401b2a1c
 called by frame at 0xbeaedbd8
 Arglist at 0xbeaedbc0, args:
 Locals at 0xbeaedbc0, Previous frame's sp is 0xbeaedbc0
(gdb) info frame 1
Stack frame at 0xbeaedbd8:
 pc = 0x401b2a1c in __libc_enable_asynccancel; saved pc 0xcdb8
 called by frame at Cannot access memory at address 0x12
(gdb) info frame 2
Stack frame at Cannot access memory at address 0x12
4

1 に答える 1

4

このスタックは破損している場合と破損していない場合があります。これは。でも発生する可能性があり-fomit-frame-pointerます。

その価値については、これが私の現在の戦略です。私はこれが最適な戦略であるとは主張していません。現時点で私にとって有効な戦略です。

  1. シンボルを取得します。コードに関する情報が多ければ多いほど、その情報を自分で再作成する必要が少なくなります。

  2. スタックを手動で再構築します。これを行うために、私は通常、スタックで見つかったポインター整列値を「情報シンボル」にフィードして、有用な情報を取得できるかどうかを確認します。シンボルがないため、既知のコード位置の近くにある値が指す可能性のあるメモリ位置で見つかった「命令」をデコードすることも役立ちます。これにより、シンボルがある場所への呼び出しが発生する可能性があります。

  3. スタックが大きくなると(ここの場合のように)、どの関数候補が最後の有効な関数と呼ばれるかを確認すると便利な場合があります。

  4. 問題を再現しようとしています。物事をライブで失敗させることができれば、すべてが桁違いに簡単になります。

  5. 次に、スタックを調べて、破損が始まったオフセットを特定します。

  6. 関数候補のアセンブリを調べて、どのデータ構造がどのオフセットに存在するかについてのヒントを取得します。

  7. 最後に、何かがメモリの一部にランダムにヒットする可能性があります(たとえば、別のスレッドがそれ自体のスタックを通り過ぎて、可能性のあるガードページを見逃し、スタックにヒットしました)。まだ手がかりがない場合は、メモリをスキャンする時間になります。スタックの破損した部分へのポインタを探し、見つけたデータ構造をリバースエンジニアリングします。

于 2012-10-23T15:06:01.550 に答える