プログラムは例外が発生すると実行を停止します。例外は、ゼロによる除算や配列のオーバーフローといったプログラムの障害を知らせるものです。ブロックを設定して、コードのどこかほかの場所で起こった式による例外を捕獲できます。
プログラムのデバッグ中、dbx を使用すると次のことが可能になります。
スタックを解放する前に処理されていない例外を捕獲する
予期できない例外を捕獲する
スタックを解放する前に、特定の例外が処理されたかどうかに関係なく捕獲する
特定の例外がプログラム内の特定の位置で起こった場合、それが捕獲される場所を決める
例外処理の発生箇所で step コマンドを実行すると、スタックの開放時に実行された最初のデストラクタの先頭に制御が戻ります。step を実行して、スタックの解放時に実行されたデストラクタを終了すると、制御は次のデストラクタの先頭に移ります。こうしてすべてのデストラクタが終了したあとに step コマンドを実行すると、例外処理の原因を扱う捕獲ブロックに制御が移ります。
exception コマンドでは、デバッグ時にいつでも 例外処理の型を確認できます。オプションなしで exception コマンドを実行するときに表示される型は、dbx 環境変数output_dynamic_type の設定で制御できます。
この変数を on に設定すると、派生型が表示されます。
この変数を off (デフォルト) に設定すると、静的な型が表示されます。
-d オプションや +d オプションを指定すると、環境変数の設定が無効になります。
-d を設定すると、派生型が表示されます。
+d を設定すると、静的な型が表示されます。
詳細については、「exception コマンド」を参照してください。
スタックを解放する前に、特定の型の例外を阻止または捕獲できます。intercept コマンドを引数を付けずに使用すると、阻止される型がリストで示されます。-all を使用すると、すべての例外が阻止されます。阻止リストに型を追加するには typename を使用します。-x を使用すると、特定の型を除外リストに格納し、阻止から除外することができます。-set を使用すると、阻止リストと除外リストの両方をクリアし、リストを指定した型のみをスローするインターセプトまたは除外に設定できます。
たとえば、int を除くすべての型を阻止するには、次のように入力します。
(dbx) intercept -all -x int |
Error 型の例外を阻止するには、次のように入力します。
(dbx) intercept Error |
CommonError 例外の阻止が多すぎた場合は、次のように入力してその除外を実行することができます。
(dbx) intercept -x CommonError |
intercept コマンド引数なしで入力すると、処理されていない例外および予期で きない例外を含んだ阻止リストが表示されます。これらの例外はデフォルトで阻止され、それに加えてクラス CommonError を除くクラス Error の例外が阻止されます。
(dbx) intercept -unhandled -unexpected class Error -x class CommonError |
Error が例外クラスのものではなく、探している例外クラスの名前が分からない 場合は、次のように入力すると、クラス Error 以外のすべての例外を阻止できます。
(dbx) intercept -all -x Error |
詳細については、「intercept コマンド」を参照してください。
unintercept コマンドは、阻止リストまたは除外リストから例外の型を削除するために使用します。引数を付けずにこのコマンドを使用すると、阻止されている型のリストが示されます (intercept コマンドに同じ)。-all を使用すると、阻止リストからすべての型を削除することができます。typename を使用すると、阻止リストから 1 つの型を削除することができます。-x を使用すると、除外リストから 1 つの型を削除することができます。
詳細については、「unintercept コマンド」を参照してください。
whocatches コマンドは、typename の例外が実行の現時点で送出された場合に、どこで捕獲されるかを報告するものです。このコマンドは、例外がスタックのトップフレームから送出された場合に何が起こるかを検出する場合に使用します。
typename を捕獲した元の送出の行番号、関数名、およびフレーム数が表示されます。捕獲ポイントがスルーを行なっている関数と同じ関数内にあると、このコマンドは、「型にはハンドルがありません」というメッセージを表示します。
詳細については、「whocatches コマンド」を参照してください。
次の例は、例外を含むサンプルプログラムを使用して、 dbx で例外処理がどのように実行されるかを示しています。型 int の例外が、関数 bar で送出されて、次の捕獲ブロックで捕獲されています。
1 #include <stdio.h> 2 3 class c { 4 int x; 5 public: 6 c(int i) { x = i; } 7 ~c() { 8 printf("destructor for c(%d)\n", x); 9 } 10 }; 11 12 void bar() { 13 c c1(3); 14 throw(99); 15 } 16 17 int main() { 18 try { 19 c c2(5); 20 bar(); 21 return 0; 22 } 23 catch (int i) { 24 printf("caught exception %d\n", i); 25 } 26 } |
サンプルプログラムからの次のトランスクリプトは、dbx の例外処理機能を示しています。
(dbx) intercept -unhandled -unexpected (dbx) intercept int <dbx> intercept -unhandled -unexpected int (dbx) stop in bar (2) stop in bar() (dbx)run Running: a.out (プロセス id 304) bar で停止しました 行番号 13 ファイル "foo.cc" 13 c c1(3); (dbx) whocatches int int が行番号 24 で捕獲されました、関数 main (フレーム番号 2) (dbx) whocatches c dbx: class c の実行時型情報がありません (送出も捕獲もされていない) (dbx) cont 例外の型 int が行番号 24 で捕獲されました、関数 main (フレーム番号 4) _exdbg_notify_of_throw で停止しました アドレス 0xef731494 0xef731494: _exdbg_notify_of_throw : jmp %o7 + 0x8 現関数 : bar 14 throw(99); (dbx) step c::~c で停止しました 行番号 8 ファイル "foo.cc" 8 printf("destructor for c(%d)\n", x); (dbx) step destructor for c(3) c::~c で停止しました 行番号 9 ファイル "foo.cc" 9 } (dbx) step c::~c で停止しました 行番号 8 ファイル "foo.cc" 8 printf("destructor for c(%d)\n", x); (dbx) step destructor for c(5) c::~c で停止しました 行番号 9 ファイル "foo.cc" 9 ) (dbx) step main で停止しました 行番号 24 ファイル "foo.cc" 24 printf("caught exception %d\n", i); (dbx) step caught exception 99 main で停止しました 行番号 26 ファイル "foo.cc" 26 } |