1

Linux で実行されている C++ プログラムを g++ でコンパイルすると、しばらくすると不正な命令例外が発生し、コア ダンプが発生するという問題があります。gdb を使用してバックトレースを実行すると、

(gdb) bt
#0  0x005e18cf in ATL_dpotrfL () from /usr/lib/liblapack.so.3gf
#1  0x00000001 in ?? ()
#2  0xb786f2e8 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

バックトレースにメインがない理由がわかりません。?? デバッグシンボルが含まれていない私のLinuxライブラリの一部のようです.

私の質問は次のとおりです。プログラムの問題は何ですか? ライブラリ lapack は間違ってコンパイルされていますか (私は数日前にコピーしました)? それとも他のエラーですか?

私は、アセンブラや同様のものを明確に飛ばしませんでした。C++ のみ。

ありがとうクリスチャン

4

3 に答える 3

7

これは通常、スタックが壊れたことを意味します。特に、0x00000001 の値は、有効なスタック アドレスである可能性が非常に低いため、スタックに割り当てられたバッファをオーバーフローさせ、リターン アドレスを上書きしたと言えます。

于 2011-08-08T11:19:37.633 に答える
2

他の人が言ったように、あなたはおそらくあなたのスタックをねじ込んだでしょう。

最も一般的な原因は次のとおりです。

  • 悪いポインタへの書き込み(すでに削除されています)
  • 点付き空間の外に書く
  • スタック上で巨大なローカルデータを宣言する

原因を見つける魔法の方法は次のとおりです。

valgrind  your_program  [args]

(通常起動するコマンドの前に「valgrind」を追加するだけです。valgrindがまだここにない場合はインストールします。これは広く使用されているツールであるため、ディストリビューションにパケットが必要です。)

次に、valgrindは、実行中にプログラムを検査し(少し遅くします)、書き込みが発生するとすぐに、プログラムが実行されるべきではない場所(たとえば、スタック上)に報告します。

于 2011-08-08T13:21:40.820 に答える
2

DeadMGの発言に加えて:

不正な命令は通常、実行中のマシンで使用できない CPU 命令を使用するようにコンパイルされたバイナリの結果です。これは、たとえば次のようにコンパイルした場合に発生する可能性があります

g++ -msse4 ...

次に、SSE4命令セットをサポートしていないIntel Atom CPUで実行します。クラッシュは必ずしも発生するとは限りません。

int main () {}

while 原因 SSE4 命令が生成されます。もちろん、現在はクラッシュしない可能性がありますが、将来的に発生する可能性が低いコードパスについても同じです。

スタック破壊コードを見つけるには、cppcheck などの LINT 、Valgrind、古き良き printf/cout の分割統治方式のデバッグ、またはチェック済みの STL 実装の使用を検討できます。

于 2011-08-08T11:31:07.177 に答える