0

メソッド A をスローすると、バッファ オーバーランが発生しますが、戻ると正常に動作します。throw は実行を呼び出し元メソッドに移動するので、それが行くアドレスは戻りアドレスと同じでなければならないと思っていましたが、明らかに間違っています。Visual Studio デバッガーでスローされるアドレスを確認する方法はありますか?

ありがとうございました

Berkus: これは、上位の呼び出し元メソッドのスタックが壊れているということですか? たとえば、

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

次に、メソッド C のリターン アドレスは問題ないのに、メソッド B のリターン アドレスが破損し、バッファ オーバーランが発生する可能性はありますか? 私が見ているのは、スローがない場合、私のアプリケーションは正常に実行されるため、メソッド A、B、および C はすべて有効なリターン アドレスを持っていると思います。

4

3 に答える 3

2

throw は、catch を含む関数に到達するまで、スタックを巻き戻します。必要に応じて、throw はスタック フレームの数レベル上に移動できるため、リターン アドレスは重要ではありません。

于 2010-06-14T17:11:16.557 に答える
0

C ++では、try / catchブロックがない場合は、次のようになります。

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

アプリケーションを終了します。終了を回避したい場合は、コードにtry/catchブロックが必要です。

于 2010-06-14T17:36:36.817 に答える
0

戻りアドレスとスローされた例外がどのように相互作用するかは、特定のコンパイラが例外処理を実装する方法の詳細に任されています。それについて確信を持って何かを言うには、ここにいる誰かがそれらの内部の詳細に精通している必要があります.

バッファー オーバーランが、例外処理によってのみ使用されるデータを破損する可能性があることは確かに考えられます (したがって、スローが失敗する原因になります)。ただし、戻りアドレスはそのまま残されます (したがって、通常の戻りが成功します)。ただし、これはコンパイラがスタックをどのように利用しているかによって異なります。(別のコンパイラでは、まったく異なる症状が発生する可能性があります)。また、破損によって、まだ気付いていない他の問題が発生している可能性もあります。または、次回コードを変更したときに、そのような破損が将来問題を引き起こす可能性があります。スタック (または C++ が依存するその他のメモリ) が破損した場合、ほぼすべてが発生する可能性があります。

教育を受けた推測作業やコンパイラの詳細に関する知識があれば、誰かが最終的にリターンアドレスとスローの仕組みに関する特定の質問に答えることができると確信しています。しかし、私は本当にこれらの質問をするのは間違っていると思います.

バッファ オーバーランが発生していることを実際に知っている場合は、これらの質問に答えようとしても意味がありません。オーバーランを修正するだけです。

オーバーランの疑いがあるだけの場合、またはオーバーランがどのように発生しているかを追跡しようとしている場合は、デバッガーでコードをステップ実行して、変数の範囲外のメモリへの変更を監視してください。または、関数を常にスローするように変更してから、プロセスの疑わしい部分を 1 つずつコメントアウトすることもできます。スローが再び機能し始めたら、問題がそこにある可能性が高いため、最後にコメントしたコードを詳しく調べることができます。これらの提案が役に立たない場合、ここで尋ねる本当の質問は、「例外のスローにのみ影響するメモリ破損を追跡するにはどうすればよいですか?」だと思います。

于 2010-06-14T18:49:08.687 に答える