2012-02-12 21 views
10

は、このコードがあります:例外ハンドラ

09 03 00 00 7a 69 6d 00 

  • 09 03 00私がスタックに見れば

    char text[] = "zim"; 
    int x = 777; 
    

    xとテキストがそこに出力され配置される場所00 = 0x309 = 777 < - int x = 777

  • 7a 69 6d 00 = char text [] = "zim"(ASCIIコード)

    char text[] = "zim"; 
    try{ 
        int x = 777; 
    } 
    catch(int){ 
    } 
    

    スタック:新しい4バイトの値を置かれ

    09 03 00 00 **97 85 04 08** 7a 69 6d 00 
    

    今テキスト間とX

は今のtry..catchとコードがあります。別のキャッチを追加すると、次のようなものが表示されます:

09 03 00 00 **97 85 04 08** **xx xx xx xx** 7a 69 6d 00 

などとなります。私はこれが例外処理と結びついたいくつかの値だと思っており、tryブロックに例外がスローされたときに適切なcatchを見つけるためにスタックの巻き戻し中に使われます。しかし、質問は、ちょうど正確にこの4バイトの値は(おそらくいくつかのアドレスを例外ハンドラの構造やいくつかのID)ですか?

32ビットLinuxマシンでg ++ 4.6を使用しています。

+0

http:// wwwを指す[C++ try/throw/catch =>マシンコード](http://stackoverflow.com/questions/1331220/c-try-throw-catch-machine-code)を参照してください。 .codeproject.com/Articles/2126/How-aC-compiler-implements-exception-handling –

+3

なぜあなたは知りたいのですか?私たちがあなたに答えを出しても、それはコンパイラとその特定のバージョンのコンパイラに固有のものです。技術的にはC++の質問ではありません。これはg ++についての質問であり、どのように動作するのですか?あなたが本当にg ++の拡張機能を書いているのでなければ、まったく役に立たない知識です。 –

+4

@ LokiAstari:* nix用のg ++​​や他のC++コンパイラは、ほとんどのプラットフォームで[Itanium ABI](http://sourcery.mentor.com/public/cxx-abi/abi-eh.html)を使用していますプラットフォーム)、それは*プラットフォーム*コンパイラ固有のものではありません。それでも、例外処理機構をどのように実装できるかを知ることは面白いことです。 –

答えて

5

AFAICTは、「巻き戻しテーブル」へのポインタです。 the Itanium ABI implementation suggestionsによれば、プロセスは「unwindテーブルを使用して、そのPCで発生する例外を処理する方法に関する情報を検索し、特に、そのアドレス範囲のパーソナリティルーチンのアドレスを取得します」。

unwindテーブルの背後にあるアイデアは、スタックの巻き戻しに必要なデータがめったに使用されないということです。したがって、スタックにポインタを置いて、別のページにデータの残量を格納する方が効率的です。最良の場合、そのページはディスク上に残り、RAMにロードする必要もありません。これと比較して、Cスタイルのエラー処理は、すべてインラインであるため、L1キャッシュで終了することがよくあります。このすべてを言うために

0

言うまでもなくこれはアドレスであってもよい

プラットフォームに依存し、などです。コードセクション(ハンドラアドレス)、またはデータセクション(フレーム情報を持つビルド時生成構造体へのポインタ)、または同じスレッドのスタック(実行時に生成されたテーブルのポインタ)を指すことがあります。フレーム情報)。 また、アラインメント要件のために残ったゴミであってもかまいませんが、これはEHが要求する可能性があります。

例えばWin32/x86では、このようなギャップはありません。例外処理を使用するすべての関数(try/catchまたは__try/__except/__finallyまたはdtorsを持つオブジェクト)では、コンパイラは(関数のプロローグコードによって)スタックに割り当てられたEXCEPTION_RECORD構造体を生成します。次に、関数内で何かが変更されると(オブジェクトが作成/破棄されると、try/catchブロックが出入りします)、コンパイラはこの構造を変更する命令を追加します(より正確には、その拡張を変更します)。しかし、何もスタックには割り当てられません。

関連する問題