質問

私はコードの断続的なクラッシュバグ(setJMPを使用)で追跡しようとしていますが、それを絞り込みました: /o2でコンパイルするときに表示され、 /o2 /oy-で消える、つまりomitでのみ表示されるフレームポインター。

http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx SETJMPにはフレームポインターが必要であることを示唆しています。したがって:

  1. SetJMPを使用するプログラムが /O2でコンパイルされている場合、Visual C ++は断続的なスタック腐敗を引き起こすコードを静かに生成するようです。これは本当ですか、それとも私は何かが足りませんか?

  2. SetJMPを呼び出す関数のみをフレームポインターでコンパイルする必要があるように思えます。プログラムの残りの部分 - LongJMPを呼び出す関数でさえ、フレームポインターを省略しても問題ありません。これは本当ですか?

編集: もう少し絞り込みました。

SetJMPを呼び出していた関数のフレームポインターを有効にすることは違いを生みませんでしたが、それはコンパイラがすでにそれを実行していたため、明らかにそれを行う必要があることに気づき、自動的にそれを行うからです。

違いを生み出したのは、メインのフレームポインターを可能にすることでした。クラッシュはメインから見返りに現れていたので、それは見た目ほど奇妙ではありません。今考えてみると、SetJMP使用のすばやいGoogle検索で見つけることができるすべての例は、主にそれを行います。おそらく、Microsoft Compilerチームがそのようにテストしただけだったのでしょう。

それを使用するための慣用的な方法であり、おそらく最高の回避策は、私がSetJMP使用関数をメインにインライン化するだけです。

役に立ちましたか?

解決

さて、私は自己完結型のテストケースを含むバグレポートを投稿したので、うまくいけば、修正がパイプラインにあります。 http://connect.microsoft.com/visualstudio/feedback/details/666704/visual-c-generates-incorrect-code-with-mit-frame-pointer-and-setjmp

それまでの間、回避策は、Frame Pointerを省略しないか、MainにSetJMPを呼び出すコードを配置しないか、setJMPへの呼び出しと同じソースファイルにlongJMPを呼び出す関数を配置します。

他のヒント

クラッシュ自体の詳細を指定していただけますか?つまり、コンパイラが生成したコンパイラをコーディングします longjmp, 、クラッシュは直後に起こりますか longjmp, 、または自動変数にアクセスしようとするとき、または関数を終了しようとするときは?

私はそれを推測します 目標 機能は標準のスタックフレームでコンパイルする必要があります。使用する関数には合理的な制限がないようです longjmp.

SETJMPはさまざまな方法で実装されていますが、これはおそらく特定のOSのアセンブリの実装と関係があります。

__stdcallを使用して関数がコンパイルされると、引数はフレームポインターに対して格納されます。あなたの実装は、上記のポインターに対してsetJMPへの引数にアクセスしている可能性があるため、コンテキストを保存する複数のレジスタをゴミ箱にぶつける必要はありません(これはsetJMPのポイントの多くを台無しにするので)。 setjmpがLinuxカーネルにこのように実装されていることを覚えているようです。

もちろん、MSVCがEBPを設定する手順を生成しない場合、これは機能せず、確実にクラッシュを引き起こします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top