プログラムは例外が発生すると実行を停止します。例外は、ゼロによる除算や配列のオーバーフローといったプログラムの障害を知らせるものです。ブロックを設定して、コードのどこかほかの場所で起こった式による例外を捕獲できます。
プログラムのデバッグ中、dbx を使用すると次のことが可能になります。
スタックを解放する前に処理されていない例外を捕獲する
予期されない例外を捕獲する
特定の例外を、スタックが解放される前に処理されたかどうかに関係なく捕獲する
特定の例外がプログラム内の特定の位置で起こった場合、それが捕獲される場所を決める
例外がスローされたポイントでの停止後、 step コマンドを発行すると、スタックの解放時に実行された最初のデストラクタの先頭に制御が戻ります。step を実行して、スタックの解放時に実行されたデストラクタを終了すると、制御は次のデストラクタの先頭に移ります。すべてのデストラクタが実行されると、step コマンドによって、例外のスローを処理する捕獲ブロックに移動します。
このセクションでは、例外を処理するための dbx コマンドについて説明します。
exception コマンドの構文を次に示します。
exception [-d | +d]
exception コマンドを使用して、デバッグ時にいつでも 例外の型を表示します。オプションなしで exception コマンドを実行した場合に、表示される型は dbxenv 変数 output_dynamic_type の設定によって判断されます。
この変数を on に設定すると、派生型が表示されます。
この変数を off (デフォルト) に設定すると、静的な型が表示されます。
-d または +d オプションを指定すると、環境変数の設定がオーバーライドされます。
-d を設定すると、派生型が表示されます。
+d を設定すると、静的な型が表示されます。
詳細については、exception コマンドを参照してください。
intercept コマンドの構文を次に示します。
intercept [-all] [-x] [-set] [typename]
スタックを解放する前に、 特定の型の例外を阻止または捕獲できます。
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 コマンドの構文を次に示します。
unintercept [-all] [-x] [typename]
引数を付けずにこのコマンドを使用すると、阻止されている型のリストが示されます (intercept コマンドに同じ)。
-all を使用すると、阻止リストからすべての型を削除することができます。typename を使用すると、阻止リストから 1 つの型を削除することができます。-x を使用すると、除外リストから 1 つの型を削除することができます。
詳細については、unintercept コマンドを参照してください。
whocatches コマンドは、 typename の例外が実行の現在のポイントでスローされた場合に、捕獲される場所を報告します。このコマンドは、例外がスタックのトップフレームから送出された場合に何が起こるかを検出する場合に使用します。
typename を捕獲した元の送出の行番号、関数名、およびフレーム数が表示されます。捕獲ポイントがスローを行なっている関数と同じ関数内にあると、このコマンドは、「type is unhandled」というメッセージを表示します。
詳細については、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 (process id 304) Stopped in bar at line 13 in file “foo.cc” 13 c c1(3); (dbx) whocatches int int is caught at line 24, in function main (frame number 2) (dbx) whocatches c dbx: no runtime type info for class c (never thrown or caught) (dbx) cont Exception of type int is caught at line 24, in function main (frame number 4) stopped in _exdbg_notify_of_throw at 0xef731494 0xef731494: _exdbg_notify_of_throw : jmp %o7 + 0x8 Current function is bar 14 throw(99); (dbx) step stopped in c::~c at line 8 in file "foo.cc" 8 printf("destructor for c(%d)\n", x); (dbx) step destructor for c(3) stopped in c::~c at line 9 in file "foo.cc" 9 } (dbx) step stopped in c::~c at line 8 in file "foo.cc" 8 printf("destructor for c(%d)\n", x); (dbx) step destructor for c(5) stopped in c::~c at line 9 in file "foo.cc" 9 ) (dbx) step stopped in main at line 24 in file "foo.cc" 24 printf("caught exception %d\n", i); (dbx) step caught exception 99 stopped in main at line 26 in file "foo.cc" 26 }