[解決済み] GDBでスタックフレームが破壊された - デバッグするには?
質問
次のようなスタックトレースがあります。ここからデバッグに役立つものを見つけ出すことは可能でしょうか。
Program received signal SIGSEGV, Segmentation fault.
0x00000002 in ?? ()
(gdb) bt
#0 0x00000002 in ?? ()
#1 0x00000001 in ?? ()
#2 0xbffff284 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb)
を得たとき、どこからコードを見ればいいのでしょうか?
Segmentation fault
が表示され、スタックトレースはあまり役に立ちません。
注:コードを投稿すれば、SOのエキスパートが答えを教えてくれるでしょう。私はSOの指導を受け、自分で答えを見つけたいので、ここにコードを投稿していません。申し訳ございません。
どのように解決するのですか?
これらの偽のアドレス (0x00000002 など) は、実際には SP 値ではなく PC 値です。 さて、偽の (非常に小さな) PC アドレスでこの種の SEGV が発生した場合、99% の場合、それは偽の関数ポインタを介して呼び出されたことが原因です。 C++の仮想呼び出しは関数ポインタを介して実装されているため、仮想呼び出しの問題はすべて同じ方法で現れる可能性があることに注意してください。
間接呼び出し命令は、呼び出し後の PC をスタックにプッシュし、PC をターゲット値 (この場合はインチキ) に設定するだけなので、もしこれが は であれば、手動でスタックから PC をポップ オフすることで簡単に元に戻せます。 32 ビット x86 コードでは、ただそうするだけです。
(gdb) set $pc = *(void **)$esp
(gdb) set $esp = $esp + 4
64ビットx86のコードでは、以下のものが必要です。
(gdb) set $pc = *(void **)$rsp
(gdb) set $rsp = $rsp + 8
次に
bt
を実行して、実際にコードがどこにあるのかを把握します。
残りの1%は、スタックを上書きしたことによるエラーで、通常はスタックに格納された配列をオーバーフローさせることで発生します。 この場合、次のようなツールを使用することで、状況をより明確にすることができるかもしれません。 valgrind
関連
-
Cエラー [エラー] 代入_Ashesの左オペランドにlvalueが必要です-プログラマーズ・シークレット
-
error: 'for' loop initial declaration is only allowed in C99 mode 原因と解決方法
-
[解決済み] Code::Blocks アプリケーションをコンパイルできない
-
[解決済み] mallocで文字列を確保する
-
[解決済み] Linuxカーネルにおけるcontainer_ofマクロの理解
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] 難読化Cコードコンテスト2006。sykes2.cの解説をお願いします。
-
[解決済み] printfは、フォーマット文字列の中に改行がないと、呼び出し後にフラッシュしないのはなぜですか?
-
[解決済み] C 言語の配列へのポインタ/ポインタの配列の曖昧さ解消
-
[解決済み] 講師が書いたC言語のファイルは、なぜ最初の行に#が一つ付いているのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
#137: 式は変更可能なlvalueでなければならない問題 // 文字列配列の代入問題
-
[C] Error [Error] 代入の左オペランドとして lvalue が必要です。
-
error: 'for' loop initial declaration is only allowed in C99 mode 原因と解決方法
-
initializer element is not constant "というエラーが表示されるのですが?
-
[解決済み] ソケットアクセプト - "開かれているファイルが多すぎる"
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] Cプリプロセッサはなぜ "linux "という単語を定数 "1 "と解釈するのですか?
-
[解決済み] C言語で関数をパラメータとして渡すにはどうすればよいですか?
-
[解決済み] なぜalloca()の使用はグッドプラクティスとみなされないのでしょうか?