[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]

# 2 デバッガの起動

本章では，デバッガの基本的なコマンド・インタフェースについて説明します。

デバッガの使用法は，デバッグの対象となるプログラムの種類，探しているエラーの種類， およびユーザの個人的な方法や経験など，いくつかの要素によって決まります。 本章では，ほとんどの状況にあてはまる，次のような基本的な作業について説明します。

- デバッガ・コマンドの入力とオンライン・ヘルプの表示

- TYPEコマンドによる画面モードでのソース・コードの表示

- GO，STEP，SET BREAKの各コマンドを使用したプログラムの実行制御と，SHOW CALLS ，SET TRACE，SET WATCHの各コマンドを使用したプログラムの実行のモニタ

- EXAMINE，DEPOSIT，EVALUATEの各コマンドを使用したデータの検査と操作

- パス名とSET MODULEコマンドおよびSET SCOPEコマンドを使用したシンボル参照の制御

ほとんどの例は，すべてのサポート言語に十分適用できまが，一部には， 言語特有のものもあります。

第2.6節内のデバッギング・ セッション例は， エラーを見つけ修正する方法を説明します。

デバッギング・セッションの開始と終了についての詳しい説明は，第1.3節を参照してください。

# 2.1 デバッガ・コマンドの入力とオンライン・ ヘルプへのアクセス

第1.3節の説明どおりにいったんデバッガを起動すると， デバッガ・プロンプト(DBG>)が表示されているときはいつでも， デバッガ・コマンドを入力できます。デバッガ・コマンドを入力するには， キーボード上でコマンドを入力してReturnキーを押します。たとえば， 次のコマンドは変数COUNTにウォッチポイントを設定します。

         DBG> SET WATCH COUNT

デバッガ・コマンドについての詳しい説明は，『デバッガ・コマンド・ディクショナリ』またはオンライン・ ヘルプで参照できます。

- ヘルプ・トピックを表示するには，プロンプトにHELPと入力する。

- ヘルプ・システムの説明を表示するには，HELP HELPと入力する。

- 完全なコマンド入力形式を表示するには，HELP Command_Format と入力する。

- 特定のコマンドについてのヘルプを表示するには，HELP commandと入力する。たとえば，SET WATCHコマンドのヘルプを表示するには，HELP SET WATCH と入力する。

- コマンドを機能別に表示するには，HELP Command_Summaryと入力する。

次のトピックについても，オンライン・ヘルプが使用できます。
新機能
リリース・ノート
アドレス式
組み込みシンボル
デバッギング構成(省略時とマルチプロセス)
DECwindowsインタフェース
キーパッド定義
言語サポート
論理名
メッセージ(診断メッセージ)
(シンボリック名を修飾する)パス名
画面モード
(プログラムからデバッガを起動する)SS$_DEBUG条件
システム管理
VWSワークステーション

上記の任意のトピックに関するヘルプを表示するには，HELP topicと入力します。たとえば，診断メッセージに関する情報を表示するには，HELP Messages と入力します。

デバッガを起動すると，よく使用されるいくつかのコマンドが，自動的にメイン・ キーボードの右側の数値キーパッド上のキーに割り当てられます。 したがって，これらの機能は，コマンドを入力するか，またはキーパッド上のキーを押すことによって実行できます。

キーパッド上の定義済みキー機能を図 2-1 に示します。

### 図 2-1 デバッガの定義済みキーパッド・キー機能-コマンド・ インタフェース

ほとんどのキーパッド・キーには，DEFAULT，GOLD，BLUEの3つの定義済み機能があります。

- あるキーのDEFAULT機能は，その目的のキーを押して実行する。

- あるキーのGOLD機能は，まずPF1 (GOLD)キーを押してから，その目的のキーを押して実行する。

- あるキーのBLUE機能は，まずPF4 (BLUE)キーを押してから，その目的のキーを押して実行する。

図 2-1では，各キーの中にDEFAULT，GOLD ，およびBLUE の各機能をそれぞれ上から下に順番に示してあります。次に例を示します。

- KP0キー(キーパッド・キー0)を押すと，STEPコマンドを実行できる。

- PF1キーを押してからKP0キーを押すと，STEP/INTOコマンドを実行できる。

- PF4キーを押してからKP0キーを押すと，STEP/OVERコマンドを実行できる。

通常，KP2，KP4，KP6，およびKP8の各キーは，それぞれ下方向，左方向， 右方向，上方向の画面スクロールを実行します。また図 2-1 に示したように，キーボードをMOVE，EXPAND，CONTRACT の各状態に設定すると，上の4つのキーを使用して，画面を4方向に移動， 拡大，または縮小できます。キーパッド・キー定義を表示するには，HELP Keypad_Definitions コマンドを入力します。

また，キーパッド・キー機能を再定義するには，DEFINE/KEYコマンドを使用します。

# 2.2 ソース・コードの表示

デバッガには，非画面モードと画面モードの2つの情報表示モードがあります。 省略時の設定では，デバッガ起動時に非画面モードになります。しかし， 画面モードでソース・コードを表示したほうがよい場合があります。 次の2つの項では，2つのモードについて簡単に説明します。

## 2.2.1 非画面モード

非画面モードは省略時の設定であり，入出力(I/O)を行用モードで表示します。 本章での会話例は，第2.2.2項を除き， すべて非画面モードを使用しています。

非画面モードでは，TYPEコマンドを使用して，1行または複数行のソース行を表示します。 たとえば，次のコマンドは，現在一時停止しているモジュールの7 行目を表示します。

         DBG> TYPE 7
         module SWAP_ROUTINES
              7:        TEMP := A;
         DBG>

ソース行の表示は，プログラムの実行とは関係ありません。現在一時停止しているモジュール以外のモジュール( コンパイル単位)からソース・コードを表示するには，TYPE コマンドにパス名を使用して，そのモジュールを指定します。 たとえば，次のコマンドは，モジュールTESTの16行目から21 行目までを表示します。

         DBG> TYPE TEST\16:21

パス名については，STEPコマンドとともに第2.3.2 項で詳しく説明します。

また，EXAMINE/SOURCEコマンドを使用すれば，特定の命令と対応するルーチンまたは他の任意のプログラム記憶位置のソース行を表示することができます。

ブレークポイント，ウォッチポイント，STEPコマンドのあと，またはトレース・ ポイントが検出されたとき(第2.3 節参照)にデバッガが実行を中断する場合は，ソース行が自動的に表示されます。

プログラム内のさまざまな記憶位置のソース行を表示したあと，現在実行が一時停止している記憶位置を再表示するには，KP5 キーを押します。

表示するソース行の位置を確定できない場合，デバッガは診断メッセージを発行します。 ソース行を表示できない理由は，いくつか考えられます。 次に例を示します。

- /DEBUG修飾子を使用しないでコンパイルまたはリンクされたモジュール内で実行が一時停止している。

- ソース・コードが使用できないシステム・ルーチンまたは共用可能イメージ・ ルーチン内で実行が一時停止している。

- ソース・ファイルが，コンパイル後に別のディレクトリに移された( ソース・ファイルの記憶位置は，オブジェクト・モジュールに組み込まれている) 。この場合，SET SOURCEコマンドを使用して新しい記憶位置を指定する。

- SET MODULEコマンドを使用して，モジュールを設定する必要がある。 モジュールの設定については，第2.5.1 項を参照。

画面モードから非画面モードに移行するには，PF1キーを押したあと，PF3 キーを押すか，またはSET MODE NOSCREENを入力します。TYPEコマンドおよびEXAMINE/SOURCE コマンドは，非画面モードだけでなく，画面モードでも使用できることに注意してください。

## 2.2.2 画面モード

画面モードは，ソース・コードを表示する最も簡単な方法を提供します。 画面モードに切り替えるには，PF3キーを押すか，またはSET MODE SCREEN と入力します。画面モードでは，図 2-2 に示すように省略時の設定により， 画面は3つの部分，すなわちSRC，OUT，およびPROMPT に分割されます。

### 図 2-2 省略時の画面モード・ディスプレイ構成

「SRC」ディスプレイは，現在実行を一時停止しているモジュールのソース・ コードを表示します。最左欄の矢印は，プログラム・カウンタ(PC)の現在値に対応するソース行を指しています。PC は，次の実行命令のメモリ・ アドレスを含むレジスタです。行番号は，コンパイラによって割り当てられますから， リスト・ファイル内の行番号と一致します。プログラムを実行するうちに， 矢印は下に移動し，矢印がディスプレイの中央になるようにソース・ コードは上にスクロールします。

「OUT」ディスプレイは，入力されたコマンドに対するデバッガの出力を表示します。 「PROMPT」ディスプレイは，デバッガのプロンプト，ユーザの入力( ユーザの入力したコマンド)，デバッガの診断メッセージ，およびプログラムの出力を表示します。

「SRC」ディスプレイと「OUT」ディスプレイをスクロールすれば，ディスプレイ・ ウィンドウに収まらない情報もすべて，スクロールして見ることができます。 スクロールするディスプレイを選択するには，KP3キーを必要なだけ繰り返し押してください。 省略時の設定では，「SRC」ディスプレイがスクロールします。 上方スクロールにはKP8キーを，下方スクロールにはKP2 キーを使用します。ディスプレイのスクロールは，プログラムの実行とは関係ありません。

画面モードで，実行を一時停止しているルーチンのソース行を確定できない場合， デバッガはソース行を表示できる，呼び出しスタック内の次のルーチンのソース行を表示しようとします。 このようなルーチンのソース行が表示された場合， デバッガは次のメッセージを発行します。

         %DEBUG-I-SOURCESCOPE, Source lines not available for .0\%PC.
         Displaying source in a caller of the current routine.
         DBG>

このような場合，「SRC」ディスプレイ内の矢印は，呼び出し元ルーチンのCALL 文の直後のコードを含む行を示します。

# 2.3 プログラム実行の制御とモニタ

この節では次の作業の実行方法について説明します。

- プログラムの実行を開始または再開する。

- プログラムを，1行単位，命令単位，または他のステップ単位で実行する。

- 現在実行が一時停止している箇所を決定する。

- ブレークポイントを使用して目的の箇所でプログラムの実行を中断する。

- トレースポイントを使用して，指定された記憶位置を通るプログラムの実行パスをトレースする。

- ウォッチポイントを使用して変数値の変化をモニタする。

これらの情報を使用すれば，第2.4節で説明するように， プログラム記憶位置を選択し，その記憶位置で変数の内容を検査および操作することができます。

## 2.3.1 プログラム実行の開始または再開

プログラムの実行を開始または再開するには，GOコマンドを使用します。

GOコマンドを使用してプログラムが開始されると，プログラムは次のいずれかのイベントが発生するまで実行を続けます。

- プログラムが実行を終了する。

- ブレークポイントに到達する。

- ウォッチポイントが検出される。

- 例外がシグナル通知される。

- ユーザがCtrl/Cを押す。

ほとんどのプログラミング言語では，プログラムがデバッガの制御下に置かれたとき， メイン・プログラムの先頭で最初に実行を一時停止します。 この時点でGOコマンドを入力すると，簡単に無限ループや例外をテストできます。

実行中に無限ループが発生すると，プログラムは終了せず，デバッガのプロンプトは再表示されません。 プロンプトを表示するには，Ctrl/Cを押して実行に割り込みをかけます( 第1.4節参照)。 画面モードを使用している場合は，ソース・ディスプレイ内のポインタが実行停止箇所を示しています。 また，SHOW CALLSコマンドを使用すれば， 呼び出しスタック内の現在アクティブなルーチン呼び出しを確認できます( 第2.3.3項を参照)。

プログラムによって処理されない例外がシグナル通知されると，デバッガはその時点で実行を中断し， ユーザがコマンドを入力できるようにします。 ユーザは，ソース・ディスプレイおよびSHOW CALLSディスプレイを見て， 実行が一時停止している箇所を見つけることができます。

GOコマンドの一般的な使用方法は，ブレークポイント，トレースポイント， およびウォッチポイントとともに使用する方法です。これらの使用方法については， それぞれ第2.3.4項，第2.3.5項， および第2.3.6 項で説明します。実行パス内にブレークポイントを設定してGO コマンドを入力すると，そのブレークポイントで実行が一時停止します。 同様に，トレースポイントを設定すると，そのトレースポイントを通して実行がモニタされます。 またウォッチポイントを設定すると，ウォッチされている変数の値が変化したとき， 実行が一時停止します。

## 2.3.2 ステップ単位でのプログラムの実行

STEPコマンドを使用すれば，プログラムを一度に1ステップまたはそれ以上の単位で実行できます。

省略時の設定では，ステップ単位はソース・コード1行です。次の例では，STEP コマンドはソース・コードを1行実行し，動作("stepped to . . . ")を報告し，次の実行行の番号(27)とソース・コードを表示します。

         DBG> STEP
         stepped to TEST\COUNT\%LINE 27
              27:   X := X + 1;
         DBG>

実行は，モジュールTEST内のルーチンCOUNT内にある行27の最初の機械語コード命令で一時停止しています。

プログラム・シンボル(たとえば，行番号，ルーチン名，または変数名など) を表示する場合，デバッガは常にパス名を使用します。パス名は， シンボルとそのシンボルの記憶位置を示す接頭辞から構成されます。 上の例では，TEST\COUNT\%LINE27がパス名です。パス名の一番左の要素はモジュール名です。 そのあとには，右に移動するにしたがって，そのシンボルを含むネストされたルーチンおよびブロックが続きます。 バックスラッシュ(\) は，要素を区切るために使用します。使用言語がAdaの場合は，Ada の構文にならってピリオドが使用されます。

パス名はデバッガに対して，プログラム内のシンボルを一意に識別します。 通常，コマンド内でパス名を使用する必要があるのは，デバッガがプログラム内のシンボルのあいまいさを解消できないときだけです( 第2.5節を参照)。通常デバッガは， 前後関係からユーザの意味するシンボルを特定できます。

STEPコマンドを使用する場合，デバッガは，コンパイラによってコード命令が生成されたソース行だけを実行可能な行とみなします。 コメント行などのその他の行は， スキップされます。

ユーザは，行単位のステップ実行の代わりに命令単位のステップ実行(SET STEP INSTRUCTION)などの異なるステップ実行モードを指定することができます。 また，省略時の設定では，呼び出されたルーチンは1ステップとして実行されます。 すなわち，呼び出されたルーチンは実行されますが， ルーチン内で実行は一時停止されません。SET STEP INTOコマンドを入力すれば， 現在実行を一時停止しているルーチン内だけでなく，呼び出されたルーチン内でも実行を中断するようデバッガに指示できます。 省略時の設定は，SET STEP OVER です。

## 2.3.3 実行停止箇所の決定

SHOW CALLSコマンドは，デバッギング・セッション中に実行が一時停止した箇所が分からない場合( たとえば，Ctrl/Cによる割り込みのあとなど)に使用します。

このコマンドは，実行が一時停止しているルーチンに至るまでの呼び出しの並びをリストします。 デバッガは，各ルーチン(実行が一時停止しているルーチンから始まる) について，次の情報を表示します。

- そのルーチンを含むモジュール名

- ルーチン名

- 呼び出しが実行された行番号(現在のルーチンの場合は，実行が一時停止された行番号)

- 対応するPC値。

  VAXプロセッサでは，PC値は，最も近い先行するシンボル値( たとえば，ルーチン)からの相対アドレスと，絶対アドレスの両方の値が表示されます。

  Alphaシステムでは，PC値は，モジュール内の先頭コード・アドレスからの相対アドレスと， 絶対アドレスの両方の値が表示されます。

次に例を示します。

         DBG> SHOW CALLS
          module name   routine name   line    rel PC    abs PC

         *TEST           PRODUCT        18    00000009  0000063C
         *TEST           COUNT          47    00000009  00000647
         *MY_PROG        MY_PROG        21    0000000D  00000653
         DBG>

この例は，モジュールTEST内のルーチンPRODUCTの18行目で実行が一時停止しており， ルーチンPRODUCTは，モジュールTEST内のルーチンCOUNTの47 行目で呼び出され，さらにルーチンCOUNTは，モジュールMY_PROG内のルーチンMY_PROG の21行目で呼び出されたことを示しています。

## 2.3.4 ブレークポイントを使用したプログラムの実行の中断

SET BREAKコマンドを使用すれば，プログラムの実行を中断する記憶位置( ブレークポイント)を選択できます。実行が中断されると， ユーザは呼び出しスタックのチェック，変数の現在値の確認などを行うことができます。GO コマンドまたはSTEPコマンドを使用して，ブレークポイントから実行を再開します。

次の例は，SET BREAKコマンドの典型的な使用方法を示したものです。

         DBG> SET BREAK COUNT
         DBG> GO
            .
            .
            .
         break at routine PROG2\COUNT
              54:  procedure COUNT(X,Y:INTEGER);
         DBG>

この例では，SET BREAKコマンドは，ルーチンCOUNT(ルーチン・コードの先頭) にブレークポイントを設定しています。そして，GOコマンドで実行を開始します。 ルーチンCOUNTに到達すると，実行は一時停止されます。 デバッガは，ルーチンCOUNTでブレークポイントに到達したことをユーザに知らせ("break at . . . ") ，実行を一時停止したソース行(54)を表示し， コマンド入力を要求するプロンプトを表示します。ユーザは，このブレークポイントでSTEP コマンドを使用してルーチンCOUNTをステップ実行したあと，EXAMINE コマンド(第2.4.1項を参照) を使用して，XおよびYの値をチェックできます。

SET BREAKコマンドの使用時には，さまざまなアドレス式(たとえば， 行番号，ルーチン名，メモリ・アドレス，バイト・オフセットなど) を使用してプログラム記憶位置を指定できます。高級言語では通常， ルーチン名，ラベル，または行番号を，必要に応じて一意性を保証するパス名とともに使用します。

ルーチン名とラベルは，ソース・コードに表示されるとおりに指定しなければなりません。 行番号は，ソース・コードのディスプレイまたはリスト・ ファイル内から求めます。行番号を指定するには，接頭辞%LINEを使用します。 この接頭辞を指定しないと，デバッガは行番号をメモリ記憶位置と解釈してしまいます。 たとえば，次のコマンドは，実行が一時停止しているモジュール内の41 行目にブレークポイントを設定します。この結果，41 行目の先頭で実行が中断されます。

         DBG> SET BREAK %LINE 41

ブレークポイントを設定できるのは，機械語コード命令に変換された行だけであることに注意してください。 それ以外の行(たとえば，コメント行) にブレークポイントを設定しようとすると，デバッガは警告を発行します。 実行が一時停止しているモジュール以外のモジュールの行番号を指定する場合は， パス名にモジュール名を含める必要があります。次に例を示します。

         DBG> SET BREAK SCREEN_IO\%LINE 58

また，パラメータなしの修飾子付きSET BREAKコマンドを使用して，行ごと， またはCALL命令ごとにブレークさせることもできます。次に例を示します。

         DBG> SET BREAK/LINE
         DBG> SET BREAK/CALL

例外，またはタスキング・プログラム内の状態移行などのイベント 発生時に，ブレークポイントを設定することもできます。

WHEN句を使用してブレークポイントを条件付きにしたり，DO句を使用してブレークポイントで実行するコマンドの並びを指定することもできます。

現在のブレークポイントを表示するには，SHOW BREAKコマンドを入力します。

ブレークポイントを無効にするには，DEACTIVATE BREAKコマンドを使用します。 その場合，ブレークポイントの設定時と全く同じようにプログラム記憶位置を指定します。 これで，プログラム実行中にそのブレークポイントは無効になります。 しかし，あとで(たとえばそのプログラムに復帰したときに( 第1.3.3項を参照))再度ブレークポイントを有効にできます。 無効にされたブレークポイントは，SHOW BREAKの表示では無効であることが示されます。

ブレークポイントを有効にするには，ACTIVATE BREAKコマンドを使用します。 このコマンドを使用すれば，プログラムの実行中にそのブレークポイントが有効になります。

DEACTIVATE BREAK/ALLコマンドとACTIVATE BREAK/ALLコマンドは，すべてのブレークポイントに対して作用し， 特にプログラムの再実行時に有効です。

ブレークポイントを取り消すには，CANCEL BREAKコマンドを使用します。 取り消されたブレークポイントは，SHOW BREAKの表示にはリストされなくなります。

## 2.3.5 トレースポイントを使用したプログラム実行のトレース

SET TRACEコマンドを使用すれば，プログラムの実行をトレースする記憶位置( トレースポイント)を選択できます。ただし，トレースポイントでプログラムの実行が停止することはありません。 トレースポイントの設定後， ユーザはGOコマンドで実行を開始し，予期しない動作をチェックしながら実行パスをモニタできます。 ルーチンにトレースポイントを設定すると， そのルーチンの呼び出し回数をモニタすることもできます。

ブレークポイントと同様，トレースポイントに到達するたびに，デバッガはメッセージを発行し， ソース行を表示します。しかし，プログラムはそのまま実行を続けるため， デバッガのプロンプトは表示されません。次に例を示します。

         DBG> SET TRACE COUNT
         DBG> GO
         trace at routine PROG2\COUNT
              54:  procedure COUNT(X,Y:INTEGER);
            .
            .
            .

ブレークポイントとトレースポイントの相違点は，この1 点だけです。SET TRACEコマンドの使用時には，SET BREAK コマンドの場合と全く同じアドレス式，修飾子，およびオプション句を使用します。SHOW TRACE ，ACTIVATE TRACE， DEACTIVATE TRACE，CANCEL TRACEの各コマンドは，トレースポイントに対してブレークポイントの対応するコマンドと同じように動作します( 第2.3.4項を参照)。

## 2.3.6 ウォッチポイントを使用した変数値の変化のモニタ

SET WATCHコマンドを使用すれば，プログラムの実行中にデバッガがモニタするプログラム変数を指定できます。 このプロセスを，ウォッチポイントの設定といいます。 ウォッチされている変数の値をプログラムが変更すると， デバッガは実行を中断し，情報を表示します。デバッガは，プログラムの実行中は常にウォッチポイントをモニタします。SET WATCH コマンドは， 変数だけでなく，プログラム内の任意の記憶位置をモニタするのにも使用できることに注意してください。

ウォッチポイントの設定方法は，システム(VAXまたはAlpha)および変数の型( 静的変数または非静的変数)によって異なります。

VAXプロセッサでは，SET WATCHコマンドとともに変数名を指定することによって， 静的変数にウォッチポイントを設定できます。 静的変数は，プログラムの実行中，常に同じメモリ・ アドレスに関連づけられているため，静的変数名は常に意味があります。 たとえば，次のコマンドは，変数TOTALにウォッチポイントを設定します。

         DBG> SET WATCH TOTAL

このあと，プログラムがTOTALの値を変更するたびに，ウォッチポイントが検出されます。

次の例は，ウォッチされている変数の内容をプログラムが変更すると次に何が起こるかを示しています。

         DBG> SET WATCH TOTAL
         DBG> GO
            .
            .
            .
         watch of SCREEN_IO\TOTAL at SCREEN_IO\%LINE 13
              13:   TOTAL = TOTAL + 1;
             old value: 16
             new value: 17
         break at SCREEN_IO\%LINE 14
              14:   POP(TOTAL);
         DBG>

この例では，ウォッチポイントが変数TOTALに設定され，実行が開始されます。 変数TOTALの値が変化すると，実行は一時停止します。デバッガは， イベントの発生をユーザに知らせ("watch of . . . ")，TOTALが変化した位置(13 行目の先頭)と，対応するソース行を表示します。そし古い値と新しい値を表示し， 次の行(14行目)の先頭で実行を一時停止します。最後に， コマンド入力を要求するプロンプトを表示します。ソース行の先頭以外で変数値が変化した場合， デバッガは行番号と行の先頭からのバイト・ オフセットを表示します。

VAXプロセッサおよびAlphaプロセッサでは，非静的変数を定義しているルーチンにトレースポイントを設定し， そのトレースポイントに到達するたびにウォッチポイントを設定するDO 句を指定することによって，その非静的変数にウォッチポイントを設定できます。 非静的変数は，スタック上またはレジスタ内に割り当てられ， その変数を定義しているルーチンが呼び出しスタック上でアクティブな場合にしか存在しないため， 常に変数名が意味を持つわけではありません( 静的変数名は常に意味があります) 。

次の例では，ルーチンROUT3内の非静的変数Yにウォッチポイントが設定されています。 トレースポイントが検出されると，WPTTRACEメッセージは非静的なウォッチポイントが設定されていることを示し，Y の値が変化するとウォッチポイントが検出されます。

         DBG> SET TRACE/NOSOURCE ROUT3 DO (SET WATCH Y)
         DBG> GO
            .
            .
            .
         trace at routine MOD4\ROUT3
         %DEBUG-I-WPTTRACE, nonstatic watchpoint, tracing every
                            instruction
            .
            .
            .
         watch of MOD4\ROUT3\Y at MOD4\ROUT3\%LINE 16
            16:     Y := 4
            old value:    3
            new value:    4
         break at MOD4\ROUT3\%LINE 17
            17:     SWAP(X,Y);
         DBG>

呼び出し元ルーチンに制御が戻ると，非静的変数はアクティブでなくなるので， デバッガは自動的にウォッチポイントを取り消し，それを示すメッセージを発行します。

Alphaプロセッサでは，デバッガはすべてのウォッチポイントを非静的なウォッチポイントとみなします。

SHOW WATCH，ACTIVATE WATCH，DEACTIVATE WATCH，CANCEL WATCHの各コマンドは， ウォッチポイントに対してブレークポイントの対応するコマンドと同じように動作します( 第2.3.4項を参照)。 ただし，非静的なウォッチポイントは，実行が，ウォッチされている変数の有効範囲内に含まれる間だけ存在します。

# 2.4 プログラム・データの検査と操作

この節では，EXAMINE，DEPOSIT，EVALUATEの各コマンドを使用して， 変数の内容の表示や変更を行ったり，式を評価したりする方法を説明します。 非静的変数の値を検査したり，値を格納したりするには，第2.3.6項で定義したように， その非静的変数の定義ルーチンがアクティブでなければなりません。

## 2.4.1 変数値の表示

変数の現在の値を表示するには，EXAMINEコマンドを使用します。EXAMINE コマンドの構文は，次のとおりです。

         EXAMINE address-expression

デバッガは，変数のコンパイラ生成データ型を認識し，それにしたがってデータを検索および編集します。 次の例は，EXAMINEコマンドのいくつかの使用例です。

文字列変数の検査

         DBG> EXAMINE EMPLOYEE_NAME
         PAYROLL\EMPLOYEE_NAME:    "Peter C. Lombardi"
         DBG>

3つの整数変数の検査

         DBG> EXAMINE WIDTH, LENGTH, AREA
         SIZE\WIDTH:   4
         SIZE\LENGTH:  7
         SIZE\AREA:   28
         DBG>

2次元の実数配列の検査(1次元当たり3要素)

         DBG> EXAMINE REAL_ARRAY
         PROG2\REAL_ARRAY
            (1,1):       27.01000
            (1,2):       31.00000
            (1,3):       12.48000
            (2,1):       15.08000
            (2,2):       22.30000
            (2,3):       18.73000
         DBG>

1次元文字配列の4番目の要素の検査

         DBG> EXAMINE CHAR_ARRAY(4)

         PROG2\CHAR_ARRAY(4): 'm'
         DBG>

レコード変数の検査(COBOLの場合)

         DBG> EXAMINE PART
         INVENTORY\PART:
             ITEM:     "WF-1247"
             PRICE:     49.95
             IN_STOCK:  24
         DBG>

レコードの構成要素の検査(COBOLの場合)

         DBG> EXAMINE IN_STOCK OF PART
         INVENTORY\IN-STOCK of PART:
             IN_STOCK:  24
         DBG>

EXAMINEコマンドでは，プログラム記憶位置の内容を表示する場合，変数名だけでなく任意の種類のアドレス式を使用できます。 デバッガは，型未定義の記憶位置には省略時のデータ型を割り当てます。 あるデータを他のデータ形式で解釈， 表示したい場合には，型付きおよび型のない位置の省略時の設定を上書きすることができます。

## 2.4.2 変数への値の代入

変数に新しい値を代入するには，DEPOSITコマンドを使用します。DEPOSIT コマンドの構文は，次のとおりです。

         DEPOSIT address-expression = language-expression

DEPOSITコマンドは，ほとんどのプログラミング言語の代入文に似ています。

次の例では，DEPOSITコマンドが，さまざまな変数に新しい値を代入しています。 デバッガは，代入された値(言語式の場合もある)が変数のデータ型と次元の制約に矛盾しないことをチェックします。

文字列の代入(文字列は，二重引用符(")または一重引用符(')で囲まなければならない)

         DBG> DEPOSIT PART_NUMBER = "WG-7619.3-84"

整数式の代入

         DBG> DEPOSIT WIDTH = CURRENT_WIDTH + 10

文字配列の12番目の要素の代入(1つのDEPOSITコマンドで代入できるのは配列の1 要素だけであり，配列全体を示す集合体は代入できない)

         DBG> DEPOSIT C_ARRAY(12) := 'K'

レコードの構成要素の代入(1つのDEPOSITコマンドで代入できるのは，レコードの1 構成要素だけであり，レコード全体を示す集合体は代入できない)

         DBG> DEPOSIT EMPLOYEE.ZIPCODE = 02172

境界外の値の代入(Xは正の整数として宣言されている)

         DBG> DEPOSIT X = -14
         %DEBUG-I-IVALOUTBNDS, value assigned is out of bounds
                 at or near DEPOSIT

EXAMINEコマンドの場合と同様，DEPOSITコマンドでは，変数名だけでなく任意の種類のアドレス式を指定できます。 あるデータを他のデータ形式で解釈したい場合は， 型付きおよび型のない位置の省略時の設定を上書きすることができます。

## 2.4.3 言語式の評価

言語式を評価するには，EVALUATEコマンドを使用します。EVALUATEコマンドの構文は， 次のとおりです。

         EVALUATE language-expression

デバッガは，現在使用している言語の演算子および式の構文を認識します。 次の例では，整変数WIDTHに値45を代入しています。そして， EVALUATEコマンドを使用して，WIDTHの現在値と7の合計を求めています。

         DBG> DEPOSIT WIDTH := 45
         DBG> EVALUATE WIDTH + 7
         52
         DBG>

次の例では，論理変数WILLINGとABLEに，それぞれTRUEとFALSEを代入しています。 そして，EVALUATEコマンドを使用して，この2つの値の論理積を求めます。

         DBG> DEPOSIT WILLING := TRUE
         DBG> DEPOSIT ABLE := FALSE
         DBG> EVALUATE WILLING AND ABLE
         False
         DBG>

# 2.5 プログラム内シンボルへのアクセス制御

プログラムに関連するシンボル(変数名，ルーチン名，ソース・コード， 行番号など)への完全なアクセスを保証するには，第1.2節で説明したように，/DEBUG 修飾子を使用してプログラムをコンパイルおよびリンクしなければなりません。

これらの条件を満たしていれば，デバッガによるシンボルの処理方法は， ほとんどの場合，ユーザには見えません。ただし，次の2つの場合は，何らかの処置が必要です。

- モジュールの設定と取り消し

- シンボルのあいまいさの解消

## 2.5.1 モジュールの設定と取り消し

シンボル検索を容易にするために，デバッガは，シンボル情報を実行可能なイメージから実行時シンボル・ テーブル(RST)にロードします。これで， シンボル情報に効率的にアクセスできるようになります。シンボルがRST 内に存在しない場合，デバッガはそのシンボルを認識しないか，または正確に解釈しません。

RSTはメモリ領域を占有するため，デバッガは，プログラムの実行中に参照されると思われるシンボルを予想しながら， 動的にシンボルをロードします。 特定のモジュールのすべてのシンボル情報が，一度にRSTテーブル内にロードされるため， このロード処理をモジュール設定と呼びます。

最初に，イメージ遷移アドレスを含むモジュールだけが設定されます。その後， プログラムの実行が中断するたびに，中断ルーチンを含むモジュールが設定されます。 この結果，ユーザは，その記憶位置で見えなければならないシンボルを参照できるようになります。

設定されていないモジュール内のシンボルを参照しようとすると，デバッガは， シンボルがRSTに設定されていないことをユーザに警告します。次に例を示します。

         DBG> EXAMINE K
         %DEBUG-W-NOSYMBOL, symbol 'K' is not in symbol table
         DBG>

このような場合は，SET MODULEコマンドを使用して，そのシンボルを含むモジュールを明示的に設定しなければなりません。 次に例を示します。

         DBG> SET MODULE MOD3
         DBG> EXAMINE K
         MOD3\ROUT2\K: 26
         DBG>

SHOW MODULEコマンドは，プログラム内のモジュールをリストし，設定されているモジュールを識別します。

動的なモジュール設定は，設定されるモジュール数が増えるにしたがって， デバッガの処理速度を低下させます。性能の低下が問題になる場合は，CANCEL MODULE コマンドを使用して設定モジュール数を減らすか，またはSET MODE NODYNAMIC コマンドを入力して動的モジュール設定を禁止します。 動的モジュール設定を使用可能にするには，SET MODE DYNAMICコマンドを使用します。

## 2.5.2 シンボルのあいまいさの解消

シンボルのあいまいさは，シンボル(たとえば，変数名X)が2つ以上のルーチン内または他のプログラム単位内で定義されているときに起こります。

ほとんどの場合，デバッガはシンボルのあいまいさを自動的に解消します。 最初に，現在設定されている言語の有効範囲および可視性規則が適用されます。 さらに，デバッガは，任意のモジュール内のシンボル指定を許可しているため( ブレークポイントを設定するときなど)，呼び出しスタック上の呼び出しルーチンの順序で， シンボルのあいまいさを解消します。

シンボルのあいまいさを解消できない場合，デバッガは次のようなメッセージを発行します。

         DBG> EXAMINE Y
         %DEBUG-W-NOUNIQUE, symbol 'Y' is not unique
         DBG>

このような場合は，そのシンボルの宣言を一意に指定するために，パス名接頭識別子を使用します。 最初に，SHOW SYMBOLコマンドを使用して，そのシンボルに対応する( そのシンボルのすべての宣言に対応する)すべてのパス名のうち， 現在RSTにロードされているものを確認します。そして， 必要なパス名接頭識別子を使用して，シンボルを参照します。次に例を示します。

         DBG> SHOW SYMBOL Y
         data MOD7\ROUT3\BLOCK1\Y
         data MOD4\ROUT2\Y
         DBG> EXAMINE MOD4\ROUT2\Y
         MOD4\ROUT2\Y: 12
         DBG>

Yの特定の宣言を繰り返して参照する必要がある場合は，SET SCOPEコマンドを使用して， シンボル検索用に新しい省略時の有効範囲を設定します。 新しい有効範囲を設定したあと，パス名接頭識別子を指定しないでYを参照すると， 新しい有効範囲内で見えるYの宣言が使用されます。次に例を示します。

         DBG> SET SCOPE MOD4\ROUT2
         DBG> EXAMINE Y
         MOD4\ROUT2\Y: 12
         DBG>

シンボル検索用の現在の有効範囲を表示するには，SHOW SCOPEコマンドを使用します。 省略時の有効範囲を復元するには，CANCEL SCOPEコマンドを使用します。

# 2.6 デバッギング・セッションの例

この節では，論理エラーを含むFORTRANプログラム(例 2-1 を参照)を例に，デバッギング・セッションの概要を示します。 この例には，本文の説明で参照されているソース行を識別できるよう， コンパイラ割り当て行番号が含まれています。

SQUARESという名前のこのプログラムは，次の機能を持っています。

1. データ・ファイルから一連の整数値を読み込んで，それらを配列INARR 内に保在する(4行目および5行目)。

2. ゼロ以外の各整数を2乗して，別の配列OUTARRにコピーするループに入る(8 行目から13行目)。

3. 元の整数列内のゼロ以外の要素の数とその各要素を2乗した値をプリントする(16 行目から21行目)。

### 例 2-1 サンプル・プログラムSQUARES

     1:       INTEGER INARR(20), OUTARR(20)
     2: C
     3: C     ---データ・ファイルから入力用の配列を読み込む
     4:       OPEN(UNIT=8, FILE='DATAFILE.DAT', STATUS='OLD')
     5:       READ(8,*) N, (INARR(I), I=1,N)
     6: C
     7: C     ---すべてのゼロ以外の要素を2乗してOUTARRに格納する
     8:       K = 0
     9:       DO 10 I = 1, N
    10:       IF(INARR(I) .NE. 0) THEN
    11:           OUTARR(K) = INARR(I)**2
    12:       ENDIF
    13:    10 CONTINUE
    14: C
    15: C     ---2乗された出力値をプリントし，終了する
    16:       PRINT 20, K
    17:    20 FORMAT(' Number of nonzero elements is',I4)
    18:       DO 40 I = 1, K
    19:       PRINT 30, I, OUTARR(I)
    20:    30 FORMAT(' Element',I4,' has value',I6)
    21:    40 CONTINUE
    22:       END

SQUARESを実行すると，データ・ファイル内のゼロ以外の要素の数に関係なく， 次のようなメッセージが出力されます。

         $ RUN SQUARES
         Number of nonzero elements is   0

このプログラムのエラーは，OUTARR内の現在のインデックス値を保持している変数 Kが，9行目から13行目までのループ内で増分されていないことです。11 行目の直前にK = K + 1という文を挿入しなければなりません。

例 2-2に，デバッギング・ セッションの開始方法とデバッガを使用してエラーを発見する方法を示します。 例のあとに，各番号に対応する説明があります。

### 例 2-2 プログラムSQUARESを使用したデバッギング・ セッション例

    $ FORTRAN/DEBUG/NOOPTIMIZE SQUARES   【1】
    $ LINK/DEBUG SQUARES   【2】
    $ SHOW LOGICAL DBG$PROCESS   【3】
    %SHOW-S-NOTRAN, no translation for logical name DBG$PROCESS

    $ DEBUG/KEEP   【4】

               Debugger Banner and Version Number

    DBG> RUN SQUARES   【5】
    %DEBUG-I-INITIAL, language is FORTRAN, module set to SQUARES$MAIN

    DBG> STEP 4   【6】
    stepped to SQUARES$MAIN\%LINE 9
         9:         DO 10 I = 1, N

    DBG> EXAMINE N,K   【7】
    SQUARES$MAIN\N:       9
    SQUARES$MAIN\K:       0

    DBG> STEP 2   【8】
    stepped to SQUARES$MAIN\%LINE 11
        11:                 OUTARR(K) = INARR(I)**2

    DBG> EXAMINE I,K   【9】
    SQUARES$MAIN\I:       1
    SQUARES$MAIN\K:       0

    DBG> DEPOSIT K = 1   【10】
    DBG> SET TRACE/SILENT %LINE 11 DO (DEPOSIT K = K + 1)   【11】

    DBG> GO   【12】
    Number of nonzero elements is   4
    Element   1 has value    16
    Element   2 has value    36
    Element   3 has value     9
    Element   4 has value    49
    %DEBUG-I-EXITSTATUS, is 'SYSTEM-S-NORMAL, normal successful completion'

    DBG> SPAWN   【13】
    $ EDIT SQUARES.FOR   【14】
       .
       .
       .
    10:       IF(INARR(I) .NE. 0) THEN
    11:           K = K + 1
    12:           OUTARR(K) = INARR(I)**2
    13:       ENDIF

       .
       .
       .
    $ FORTRAN/DEBUG/NOOPTIMIZE SQUARES   【15】
    $ LINK/DEBUG SQUARES
    $ LOGOUT   【16】

    DBG> RUN SQUARES   【17】
    %DEBUG-I-INITIAL, language is FORTRAN, module set to SQUARES$MAIN
    DBG> SET BREAK %LINE 12 DO (EXAMINE I,K)   【18】

    DBG> GO   【19】
    SQUARES$MAIN\I:        1
    SQUARES$MAIN\K:        1

    DBG> GO
    SQUARES$MAIN\I:        2
    SQUARES$MAIN\K:        2

    DBG> GO
    SQUARES$MAIN\I:        4
    SQUARES$MAIN\K:        3
    DBG> EXIT   【20】
    $

次の説明は，例 2-2内の番号に対応しています。 例 2-1は，デバッグ中のプログラムを示しています。

【1】
  DCL FORTRANコマンドの/DEBUG 修飾子は，プログラムのコードおよびデータに加えて，SQUARES に関連するシンボル情報をオブジェクト・モジュールSQUARES.OBJに書き込むようコンパイラに指示します。

  /NOOPTIMIZE修飾子は，Fortranコンパイラの最適化を禁止して，実行可能なコードとプログラムのソース・ コードが一致するようにしています。最適化されたコードをデバッグすると， いくつかのプログラム記憶位置の内容とソース・ コードの表示内容とが一致しないことがあるため，混乱を招きます。

【2】
  DCL LINKコマンドに/DEBUG修飾子を指定すると， リンカは，SQUARES.OBJ内に存在するすべてのシンボル情報を実行可能なイメージに含めます。
【3】
  デバッガは，論理名DBG$PROCESS の定義に従って，省略時の構成またはマルチプロセス構成のどちらかで起動できます。 この例では，SHOW LOGICAL DBG$PROCESSコマンドによって，DBG$PROCESS が未定義であり，省略時の構成が有効であることが分かります。 これは，SQUARESのような1プロセス内だけで動作するプログラムに適切な構成です。
【4】
  DCLコマンドDEBUG/KEEPが，デバッガを起動します。起動されると， バナーとデバッガ・ プロンプトDBG>が表示されます。ユーザは，デバッガ・コマンドが入力できるようになります。
【5】
  デバッガ・コマンドRUN SQUARES は，プログラムSQUARESをデバッガの制御下に置きます。情報メッセージは， プログラムのソース言語とメイン・プログラム単位名(この例では， それぞれFORTRANとSQUAR ES)を表示します。

  最初にメイン・プログラム単位の先頭(この例では，SQUARESの1行目)で実行は一時停止します。

【6】
  READ文が実行され，Kに0が代入されたあと， 変数NとKの値をテストします。

  コマンドSTEP 4によって，プログラムのソース行が4行実行されます。9行目で実行は一時停止します。STEP コマンドは，実行可能なコードに変換されなかったソース行を無視することに注意してください。 また，省略時の設定では， デバッガは実行が一時停止したソース行を表示します。

【7】
  コマンドEXAMINE N,Kが，NとKの現在値を表示します。この時点では， これらは正しい値を示しています。
【8】
  コマンドSTEP 2によって， プログラムはループに入り，INARRのゼロ以外のすべての要素の2 乗をOUTARR内にコピーします。
【9】
  コマンドEXAMINE I,Kが，I とKの現在値を表示します。

  Iの値は，予想どおり1です。しかし，Kの値は0になっており，予想していた値1 ではありません。ここでエラーが発見されました。Kは， ループ内の11行目で使用される直前に増分されなければなりません。

【10】
  DEPOSITコマンドを使用して，Kに正しい値1を代入します。
【11】
  ここで，SET TRACEコマンドを使用してプログラムをパッチし，K の値がループ内で自動的に増分されるようにします。 このコマンドは，実行が11行目に到達するたびに検出されるトレースポイントを設定します。

  - /SILENT修飾子は，"trace at"メッセージを抑制する。/SILENT 修飾子を指定しないと，11行目が実行されるたびにこのメッセージが表示される。

  - DO句は，トレースポイントが検出されるたびにコマンドDEPOSIT K = K + 1 を発行する。
【12】
  パッチをテストするために，GOコマンドで，現在の記憶位置から実行を開始します。

  プログラムの出力は，パッチされたプログラムが正しく動作したことを示します。EXITSTATUS メッセージは，プログラムが最後まで実行されたことを示します。

【13】
  SPAWNコマンドでサブプロセスを作成して， デバッギング・セッションを終了することなく一時的にDCLレベルに制御を戻します。 ここで，ソース・ファイルを修正し，プログラムを再度コンパイルおよびリンクします。
【14】
  EDITコマンドでエディタを起動し， ソース・ファイルを編集して，10行目の後ろにK = K + 1を挿入します。 例では，明確にするために，コンパイラ割り当て行番号が付加されています。
【15】
  修正されたプログラムをコンパイルおよびリンクします。
【16】
  作成されたサブプロセスをLOGOUTコマンドによって終了し， デバッガに制御を戻します。
【17】
  デバッガ・ コマンドRUN SQUARESは，修正されたプログラムをデバッガの制御下に置き， 正しく動作することを確認できるようにします。
【18】
  SET BREAKコマンドを使用して，12行目が実行されるたびに検出されるようにブレークポイントを設定します。DO 句は，ブレークポイントが検出されると， 自動的にIとKの値を表示します。
【19】
  GOコマンドで実行を開始します。

  最初のブレークポイントでは，Kの値は1になっており，ここまではプログラムが正常に動作していることを示しています。GO コマンドを実行するたびにI とKの現在値が表示されます。2つのGOコマンドのあと，Kは予想どおり3 になっていますが，Iは4になっていることに注意してください。これは，INARR の要素の1つがゼロであるため，DOループの繰り返しで11行目と12 行目が実行されなかったKが増分されなかった)からです。これで，プログラムが正しく動作していることが確認できます。

【20】
  EXIT コマンドによってデバッギング・セッションを終了し，DCLレベルに制御を戻します。

[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]