2012-01-12 10 views
2

現在、catch(...)ブロック内にあるプロセスにGDBが接続されています。C++ catch(...)ブロックでスローされた例外にアクセスできる

スローされた例外にアクセスするための既知のテクニックはありますか?

問題のプログラムはgcc/x86-64バイナリですが、他のビルドについても興味があります。

+1

もちろん、それはまだ存在しますが、あなたはそのタイプを知らないので、あなたはそれをどうしますか? –

+1

ええ、おそらくアクティブな例外オブジェクトに対していくつかのRTTIを行うことができます。 ABIのドキュメントを確認してください。 ... –

答えて

4

あなたは、あなたがそれを再スローすることができ、言うように、あなたは(あなたにもしたい場合は、別の...)の例外を抽出するために、より具体的な条項を持つ別のtry/catchブロック内に再投げることができるようにします。別の関数の中でこれを行うこともできますので、例外処理を集中化することができます。

編集:私はあなたの質問でgdbの重要性を誤解しましたが、私が説明した考えを適用することができます。ただcall helper()を行うgdbに続いて

void 
helper() 
{ 
    try { 
     throw; 
    } catch (int i) { 
     // anything that won't get optimized away 
     volatile int j = i; // breakpoint here 
    } 
} 

:あなたがにブレークポイントを設定することができ、例外を再スローする機能を確認します。私はちょうどそれが働いたことを確認するためにこれをテストした

さらに編集:あなたは文字通り、私はgdbのの下でプログラムを実行しているを意味し、あなたが例外を得ることができないことを確認するまで、あなたはgdbを終了していない場合、それはeh_throw.ccを見て時間ですgccの情報源にあります。 __cxa_rethrow開始:

__cxa_eh_globals *globals = __cxa_get_globals(); 
    __cxa_exception *header = globals->caughtExceptions; 

あなたが内部に埋め込まれているものを把握するために、これらの構造のすべてを検討する必要があります。

1

私はこれをテストしていませんが、例外(または少なくともポインタ)はおそらくスタックのどこかにあるべきです。私は正確な位置と形式は実装に依存していると思いますが、スタックのこの領域の異なるアドレスを例外タイプ(または少なくともstd :: exception)にキャストして意味のある結果が得られるかどうかを確認する必要があります。

+1

スタックのウォークバック中に永続化する必要があるため、例外はスタック上にあることはできません。ほとんどの実装では、特別な区域が割り当てられていますが、この領域にはC++からアクセスできません。 –

+0

@James - それへのポインタはおそらくスタックにあります。そして、例外のコピーをスタックに置くことができます。このコードは、例外をコピーする 'catch(std :: exception ex)'を持つことができます。このように '...'が実装されていることはありませんが、可能です。 – Asaf

+0

これは、ポインタがスタック上にあった実装を見たことがありません。 'catch 'のセマンティクスは、関数の多かれ少なかれです:あなたが値でキャッチした場合、ローカルコピーを取得します。参照によってcatchすると、例外を参照し、 'catch(...)'した場合、ランタイムはargなしで関数を呼び出すときよりもスタックにそれ以上のものを置かない。 –

関連する問題