Oracle Solaris Studio 12.2: dbx コマンドによるデバッグ

dbx での例外処理

プログラムは例外が発生すると実行を停止します。例外は、ゼロによる除算や配列のオーバーフローといったプログラムの障害を知らせるものです。ブロックを設定して、コードのどこかほかの場所で起こった式による例外を捕獲できます。

プログラムのデバッグ中、dbx を使用すると次のことが可能になります。

例外処理の発生箇所で step コマンドを実行すると、スタックの開放時に実行された最初のデストラクタの先頭に制御が戻ります。step を実行して、スタックの解放時に実行されたデストラクタを終了すると、制御は次のデストラクタの先頭に移ります。こうしてすべてのデストラクタが終了したあとに step コマンドを実行すると、例外処理の原因を扱う捕獲ブロックに制御が移ります。

例外処理コマンド

exception [-d | +d] コマンド

exception コマンドでは、デバッグ時にいつでも 例外処理の型を確認できます。オプションなしで exception コマンドを実行するときに表示される型は、dbx 環境変数 output_dynamic_type の設定で制御できます。

-d オプションや +d オプションを指定すると、環境変数の設定が無効になります。

詳細については、exception コマンド」を参照してください。

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 [-all] [-x] [typename] コマンド

unintercept コマンドは、阻止リストまたは除外リストから例外の型を削除するために使用します。引数を付けずにこのコマンドを使用すると、阻止されている型のリストが示されます (intercept コマンドに同じ)。-all を使用すると、阻止リストからすべての型を削除することができます。typename を使用すると、阻止リストから 1 つの型を削除することができます。-x を使用すると、除外リストから 1 つの型を削除することができます。

詳細については、unintercept コマンド」を参照してください。

whocatches typename コマンド

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   }