dbx コマンドによるデバッグ ホーム目次前ページへ次ページへ索引


第 15 章

C++ のデバッグ

この章では、dbx による C++ の例外の処理方法と C++ テンプレートのデバッグについて説明します。これらの作業を実行するために使用するコマンドの要約とコード例も示します。

この章は次の各節から構成されています。

C++ プログラムのコンパイルの詳細については、「最適化コードのデバッグ」を参照してください。

C++ での dbx の使用

この章では C++ デバッグの 2 つの特殊な点を中心に説明しますが、dbx を使用すると、C++ プログラムのデバッグに次の機能を利用することができます。

これらの詳細については、索引の C++ の下の項目を参照してください。

dbx での例外処理

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

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

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

例外処理コマンド

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

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

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

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「exception コマンド」を参照してください。

intercept [-a|-x|typename] コマンド

スタックを解放する前に、特定の型の例外を阻止または捕獲できます。intercept コマンドを引数を付けずに使用すると、阻止される型がリストで示されます。-a を使用すると、すべての例外が阻止されます。阻止リストに型を追加するには typename を使用します。-x を使用すると、特定の型を阻止から除外することができます。

たとえば、int を除くすべての型を阻止するには、次のように入力します。

(dbx) intercept -a
(dbx) intercept -x int

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「exception コマンド」を参照してください。

unintercept [-a|-x |typename] コマンド

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

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「exception コマンド」を参照してください。

whocatches typename コマンド

whocatches コマンドは、typename の例外が実行の現時点で送出された場合に、どこで捕獲されるかを報告するものです。このコマンドは、例外がスタックのトップフレームから送出された場合に何が起こるかを検出する場合に使用します。

typename を捕獲した元の送出の行番号、関数名、およびフレーム数が表示されます。

例外処理の例

次の例は、例外を含むサンプルプログラムを使用して、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
実行中: a.out 
(process 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   }

C++ テンプレートでのデバッグ

dbx は C++ テンプレートをサポートしています。クラスおよび関数テンプレートを含むプログラムを dbx に読み込み、クラスや関数に対して使用する任意の dbx コマンドをテンプレートに対して次のように呼び出すことができます。

テンプレートの例

次のコード例は、クラステンプレート Array とそのインスタンス化、および関数テンプレート square とそのインスタンス化を示しています。

 1		template<class C> void square(C num, C *result)
 2		{
 3	 		*result = num * num;
 4		}
 5	
 6		template<class T> class Array
 7		{
 8		public:
 9	  		int getlength(void)
10	 		{ 
11	    			return length;
12	  		}
13	
14	  		T & operator[](int i)
15	  		{
16	    			return array[i];
17	 		}
18	
19	  		Array(int l)
20	  		{ 
21	    			length = l; 
22	    			array = new T[length];
23	  		} 
24	  
25	 	 	~Array(void)
26	  		{ 
27	   	 		delete [] array;
28	  		} 
29	
30		private:  
31	  		int length; 
32	  		T *array; 
33		}; 
34	 
35		int main(void)
36		{ 
37	  		int i, j = 3; 
38	 		square(j, &i); 
39	 
40	 		double d, e = 4.1; 
41	  		square(e, &d); 
42	   

43	  		Array<int> iarray(5); 
44	  		for (i = 0; i < iarray.getlength(); ++i)
45	  		{ 
46	   			iarray[i] = i; 
47	 		} 
48	  
49	  		Array<double> darray(5);     
50	  		for (i = 0; i < darray.getlength(); ++i)
51	 		{  
52	    			darray[i] = i * 2.1;
53	  		} 
54	   
55	  		return 0; 
56		}

この例の内容は次のとおりです。

C++ テンプレートのコマンド

以下に示すコマンドは、テンプレートおよびインスタンス化されたテンプレートに使用します。クラスまたは型定義がわかったら、値の出力、ソースリストの表示、またはブレークポイントの設定を行うことができます。

whereis name コマンド

whereis コマンドは、関数テンプレートまたはクラステンプレートの、インスタンス化された関数やクラスの出現すべてのリストを出力するために使用します。

クラステンプレートの場合は、次のように入力します。

(dbx) whereis Array
メンバー関数: `Array<int>::Array(int)
メンバー関数: `Array<double>::Array(int)
クラステンプレートインスタンス: `Array<int>
クラステンプレートインスタンス: `Array<double>
クラステンプレート: `a.out`template_doc_2.cc`Array

関数テンプレートの場合は、次のように入力します。

(dbx) whereis square
関数テンプレートインスタンス: `square<int>(__type_0,__type_0*)
関数テンプレートインスタンス: `square<double>(__type_0,__type_0*)
関数テンプレート:      `a.out`square

_type_0 パラメータは、0 番めのパラメータを表します。_type_1 パラメータは、次のパラメータを表します。

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「whereis コマンド」を参照してください。

whatis name コマンド

関数テンプレートおよびクラステンプレートと、インスタンス化された関数やクラスの定義を出力するために使用します。

クラステンプレートの場合は、次のように入力します。

(dbx) whatis Array
template<class T> class Array ;
完全なテンプレート宣言を得るために次を実行してください:
'whatis -t Array<int>';

クラステンプレートとの構造については次のように実行します。

(dbx) whatis Array
複数の識別子 'Array'.
次のどれかを選択してください:
 0) Cancel
 1) Array<int>::Array(int)
 2) Array<double>::Array(int>
> 1
Array<int>::Array(int 1);

関数テンプレートの場合は、次のように入力します。

(dbx) whatis square
複数の識別子 'square'.
次のどれかを選択してください:
 0) Cancel
 1) square<int(__type_0,__type_0*)
 2) square<double>(__type_0,__type_0*)
> 2
void square<double>(double num, double *result);

クラステンプレートのインスタンス化の場合は、次のように入力します。

(dbx) whatis -t Array<int>
class Array<int> {
public:
   int Array<int>::getlength();
   int &Array<int>::operator[](int i);
   Array<int>::Array<int>(int l);
   Array<int>::~Array<int>();
private:
   int length;
   int *array;
};

関数テンプレートのインスタンス化の場合は、次のように入力します。

(dbx) whatis square(int, int*)
void square(int num, int *result);

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「whatis コマンド」と「C++ で使用する whatis コマンド」を参照してください。

stop inclass classname コマンド

テンプレートクラスのすべてのメンバー関数を停止するには、次のように入力します。

(dbx)stop inclass Array
(2) stop inclass Array

stop inclass コマンドを使用して、特定のテンプレートクラスのメンバー関数すべてにブレークポイントを設定します。

(dbx) stop inclass Array<int>
(2) stop inclass Array<int>

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「stop コマンド」を参照してください。

stop infunction name コマンド

stop infunction コマンドを利用して、 指定した関数テンプレートのインスタンスにブレークポイントを設定します。

(dbx) stop infunction square
(9) stop infunction square

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「stop コマンド」を参照してください。

stop in function コマンド

stop in コマンドを使用して、あるテンプレートクラスのメンバー関数、またはテンプレート関数にブレークポイントを設定します。

クラスインスタンス化のメンバーの場合は、次のとおりです:

(dbx) stop in Array<int>::Array<int>(int l)
(2) stop in Array<int>::Array<int>(int)

(dbx) stop in square(double, double*)
(6) stop in square(double, double*)

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「stop コマンド」を参照してください。

call function_name (parameters) コマンド

スコープ内で停止した場合に、関数インスタンス化やクラステンプレートのメンバー関数を明示的に呼び出すには、call コマンドを使用します。dbx で正しいインスタンスを選択できない場合、表示されるメニューを利用します。

(dbx) call square(j,i)

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「call コマンド」を参照してください。

print コマンド

print コマンドを使用して、インスタンス化された関数またはクラステンプレートメンバー関数を評価します。

(dbx) print iarray.getlength() 
iarray.getlength() = 5

print を使用して this ポインタを評価します。

(dbx) whatis this
class Array<int> *this;
(dbx) print *this
*this = {
length = 5
array = 0x21608
}

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「print コマンド」を参照してください。

list コマンド

list コマンドを使用して、指定のインスタンス化された関数のソースリストを出力します。

(dbx) list square(int, int*)

詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「list コマンド」を参照してください。


サン・マイクロシステムズ株式会社
Copyright information. All rights reserved.
ホーム   |   目次   |   前ページへ   |   次ページへ   |   索引