Compaq OpenVMS
デバッガ説明書


前へ 次へ 目次 索引


17.6.4 タスク・イベントのモニタ

SET BREAK/EVENT コマンドと SET TRACE/EVENT コマンドを使用すれば,タスク・イベントと例外イベントによって検出されるブレークポイントおよびトレースポイントを設定できます。たとえば,次のコマンドで設定するトレースポイントは,タスク CHILDか%TASK 2 が RUN 状態に移るときに検出されます。


DBG> SET TRACE/EVENT=RUN CHILD,%TASK 2

あるイベントの結果,ブレークポイントかトレースポイントが検出されると,デバッガはそのイベントを識別し,追加情報を与えます。

次の各表に,SET BREAK/EVENT コマンドと SET TRACE/EVENT コマンドに\ 指定できるイベント名キーワードの一覧を示します。

表 17-6 下位レベルの汎用タスクのスケジューリング・イベント
イベント名 機能
RUN タスクが実行する直前に検出される。
PREEMPTED RUN状態にあるタスクが強制的に READY 状態に移される直前に検出される(表 17-3 を参照)。
ACTIVATING タスクが実行を開始する直前に検出される。
SUSPENDED タスクが中断される直前に検出される。

表 17-7 POSIX Threads依存イベント
イベント名 機能
HANDLED ある TRY ブロックで例外が処理される直前に検出される。
TERMINATED タスクが終了する直前に検出される(警告や例外による場合を含む)。
EXCEPTION_TERMINATED タスクが例外によって終了する直前に検出される。
FORCED_TERM タスクが警告処理によって終了する直前に検出される。

表 17-8 Ada固有のイベント
イベント名 機能
HANDLED 例外が Ada の例外ハンドラ(その他のハンドラを含む)によって処理される直前に検出される。
HANDLED_OTHERS 例外がその他の Ada 例外ハンドラによって処理される直前にだけ検出される。
RENDEZVOUS_EXCEPTION 例外がランデブの外に通知される直前に検出される。
DEPENDENTS_EXCEPTION 例外によってタスクがある有効範囲内の依存タスクを待つ直前に検出される(未処理例外1 を含む。したがって,Compaq Ada の実行時ライブラリ内部の特殊な例外を含む。詳しくは,Compaq Ada のマニュアルを参照)。デッドロックの直前のことが多い。
TERMINATED タスクの終了直前に検出される。正常終了のとき,abort 文によるとき,および例外によるときを含む。
EXCEPTION_TERMINATED 処理されない例外1 によってタスクが終了する直前に検出される。
ABORT_TERMINATED abort 文によってタスクが終了する直前に検出される。


1未処理例外とは,現在のフレーム内にそのためのハンドラがない例外,またはハンドラがあって raise 文を実行しその例外を外部有効範囲に通知する例外のことです。

上記の各表には,例外関係のイベントも含めてあります。次の各段落では,タスク・イベントについてだけ説明しています。例外イベントについての詳しい説明は,デバッガのオンライン・ヘルプを参照してください(type Help Language_Support Ada を入力します)。

イベント名キーワードは,一意性を損わない文字数まで短縮できます。

SET BREAK/EVENT コマンドまたは SET TRACE/EVENT コマンドに指定できるイベント名キーワードは,そのときのイベント機能がタスク・イベント時に THREADS なのか ADA なのかで異なります。プログラムをデバッガの制御下に置くと,適切なイベント機能が自動的に設定されます。SHOW EVENT_FACILITY コマンドでは,現在設定されている機能が示され,その機能に指定できるイベント名キーワード(汎用イベントのキーワードを含む)の一覧が表示されます。

以後,いくつかの例によって /EVENT 修飾子の使用法を示します。


DBG> SET BREAK/EVENT=PREEMPTED
DBG> GO
break on THREADS event PREEMPTED 
  Task %TASK 4 is getting preempted by %TASK 3
   .
   .
   .
DBG> SET BREAK/EVENT=SUSPENDED
DBG> GO
break on THREADS event SUSPENDED 
  Task %TASK 1 is about to be suspended
   .
   .
   .
DBG> SET BREAK/EVENT=TERMINATED
DBG> GO
break on THREADS event TERMINATED 
  Task %TASK 4 is terminating normally
DBG>

プログラムをデバッガの制御下に置くと,次の定義済みイベント・ブレークポイントが自動的に設定されます。

以後,Ada での定義済みおよびその他の型のイベント・ブレークポイント例を示します。

EXCEPTION_TERMINATEDイベントの例

EXCEPTION_TERMINATED イベントが起動されるときには,通常,予期しないプログラム・エラーが示されます。次に例を示します。


...
break on ADA event EXCEPTION_TERMINATED 
  Task %TASK 2 is terminating because of an exception 
    %ADA-F-EXCCOP, Exception was copied at a "raise;" or "accept" 
    -ADA-F-EXCEPTION, Exception SOME_ERROR 
    -ADA-F-EXCRAIPRI, Exception raised prior to PC = 00000B61 
DBG> 

DEPENDENTS_EXCEPTIONイベントの例(Ada)

Ada プログラムの場合,DEPENDENTS_EXCEPTION イベントが起こると,そのあとにデッドロックが続くことがよくあります。次に例を示します。


...
break on ADA event DEPENDENTS_EXCEPTION 
  Task %TASK 2 may await dependent tasks because of this exception: 
    %ADA-F-EXCCOP, Exception was copied at a "raise;" or "accept" 
    -ADA-F-EXCEPTION, Exception SOME_ERROR 
    -ADA-F-EXCRAIPRI, Exception raised prior to PC = 00000B61 
DBG> 

RENDEZVOUS_EXCEPTIONイベントの例(Ada)

Ada プログラムの場合,RENDEZVOUS_EXCEPTION イベントを指定しておけば,制御がランデブを離れる前に(例外情報が呼び出しタスクにコピーされて失われる前に)その例外を見ることができます。次に例を示します。


...
break on ADA event RENDEZVOUS_EXCEPTION 
  Exception is propagating out of a rendezvous in task %TASK 2 
    %ADA-F-CONSTRAINT_ERRO, CONSTRAINT_ERROR 
    -ADA-I-EXCRAIPRI, Exception raised prior to PC = 00000BA6 
DBG> 

/EVENT 修飾子によって設定されたブレークポイントまたはトレースポイントを取り消すには,CANCEL BREAK/EVENT または CANCEL TRACE/EVENT コマンドを使用します。SET コマンドのときとまったく同じように,CANCEL コマンドにイベント修飾子とオプションのタスク式を指定します。ただし,WHEN 句や DO 句は指定しません。

タスキング・プログラム用のデバッガ初期化ファイルに,イベント・ブレークポイントとトレースポイントを設定したいことがあります。次に例を示します。


SET BREAK/EVENT=ACTIVATING 
SET BREAK/EVENT=HANDLED DO(SHOW CALLS)
SET BREAK/EVENT=ABORT_TERMINATED DO(SHOW CALLS)
SET BREAK/EVENT=EXCEPTION_TERM DO(SHOW CALLS)
SET BREAK/EVENT=TERMINATED 

17.7 タスク・デバッグについての補足

次の各項では,タスク・デバッグに関係する次の補足事項について説明します。

17.7.1 デッドロック状態になるプログラムのデバッグ

デッドロック とは,あるタスク・グループ内の各タスクが中断されて,そのグループ内のどれか別のタスクが実行されないかぎり,グループ内のどのタスクも実行を再開できないエラー状態のことです。デッドロックは,タスキング・プログラムでよく起こるエラーです。WHILE 文を使用するプログラムでは無限ループがよく起こるエラーであるのと同様です。

デッドロックは簡単に検出できます。この状態のプログラムは実行を中断しているように見えます。デバッガの制御下で実行しているプログラムがデッドロックを起こしたときには,Ctrl/C を押します。そのデッドロックが中断され,デバッガのプロンプトが表示されます。

通常は,SHOW TASK/ALL コマンド(第 17.4 節 を参照)か SHOW TASK/STATE=SUSPENDED コマンドが役立ちます。プログラム内の中断しているタスクとその理由が示されるからです。画面モードでデバッグしているときは,SET TASK/VISIBLE %NEXT_TASK コマンドがたいへん便利です。これを使用すれば,すべてのタスクを調べ,各タスクが実行しているコード(実行が停止しているコードを含む)を表示できるからです。

SHOW TASK/FULL コマンドでは,ランデブ情報,エントリ呼び出し情報,エントリ索引値などのタスク状態についての詳しい情報が得られます。SET BREAK/EVENT コマンドや SET TRACE/EVENT コマンド(第 17.6.4 項 を参照)では,デッドロックを引き起こす可能性がある記憶位置かその近くにブレークポイントやトレースポイントを設定できます。SET TASK/PRIORITY コマンドと SET TASK/RESTORE コマンドでは,まったく実行されない低優先順位のタスクがデッドロックを引き起こしているのかどうかが分かります。

表 17-9 に,さまざまなタスクのデッドロック状態と,その原因の診断に役立つと思われるデバッガ・コマンドの一覧を示します。

表 17-9 Adaタスクのデッドロック状態とそれを診断するためのデバッガ・コマンド
デッドロック状態 デバッガ・コマンド
自己呼び出しデッドロック(タスクが自分自身のエントリの 1 つを呼び出す) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
循環呼び出しデッドロック(あるタスクが別のタスクを呼び出し,呼び出されたタスクが最初のタスクを呼び出す) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
動的呼び出しデッドロック(一連のエントリ呼び出しが循環し,そのうちの少なくとも1つがループ内の時限または条件付きエントリ呼び出しである) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
例外によって生じるデッドロック(例外によって,タスクがそのエントリ呼び出しの1つに応えられないまたは例外の通知が依存タスクを待たなければならない) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
SET BREAK/EVENT=DEPENDENTS_EXCEPTION(Adaプログラムの場合)
エントリ索引に対する実行時の計算間違い,when条件,およびselect文内のdelay文によるデッドロック SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
EXAMINE
エントリが間違った順番で呼び出されたためのデッドロック SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
優先順位の低いタスクによって設定される変数をフラグとして使用するが,それより優先順位の高いタスクがいつもレディ状態のため優先順位の低いタスクがまったく実行できなくて生じる,変数の変更待ちデッドロック SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
SET TASK/PRIORITY
SET TASK/RESTORE

17.7.2 デバッガによる自動スタック・チェック

タスキング・プログラムの場合,ある種の状況では検出されないスタック・オーバフローが起こり,予期しない処理が行われることがあります。タスク・スタック・オーバフローについての詳しい説明は,Compaq Adaか POSIX Threads のマニュアルを参照してください。デバッガによって自動的に次のスタック・チェックが行われるので,スタック・オーバフローの問題の原因を探り出すのに役立ちます。スタック・ポインタが境界を越えている場合は,エラー・メッセージが表示されます。

次のエラー・メッセージ例は,スタック・チェックによってエラーが見つかったときに発行されるものです。たとえスタックがまだオーバフローしていなくても,スタックの大半が使用し尽くされているときには,警告メッセージが発行されます。


warning: %TASK 2 has used up over 90% of its stack 
  SP: 0011194C  Stack top at: 00111200  Remaining bytes: 1868 
 
error: %TASK 2 has overflowed its stack 
  SP: 0010E93C  Stack top at: 00111200  Remaining bytes: -10436 
 
error: %TASK 2 has underflowed its stack 
  SP: 7FF363A4  Stack base at: 001189FC  Stack top at: 00111200 

スタックのオーバフローに続いてスタックのアンダフローが起こることがあります。その経過は次のとおりです。タスク・スタックがオーバフローしてスタック・ポインタが上部保護領域を指したままでいるとき,オペレーティング・システムは ACCVIO 状態をシグナル通知しようとします。しかし上部保護領域には ACCVIO のシグナル引数を書き込めないので,オペレーティング・システムはスタックの別の場所を探します。つまり,フレーム・ポインタとスタック・ポインタがメイン・プログラムのスタック領域の基底を指すようにしてシグナル引数を書き込み,プログラム・カウンタを変更してイメージを強制終了します。

このときタイム・スライス AST かその他の AST が発生すると,別のタスクの実行が再開し,しばらくの間は正常でないままプログラムが続行することがあります。スタックがオーバフローしたタスクは,メイン・プログラムのスタックを使用し,重ね書きすることがあります。デバッガのスタック・チェックは,このような状態を検出するのに役立ちます。オペレーティング・システムによってスタックの規定外の箇所に書き込みをされたタスク内の命令をステップ実行すれば,またはそのときに SHOW TASK/ALL コマンドを使用すれば,デバッガからスタック・アンダフロー・メッセージが発行されます。

17.7.3 AdaタスクをデバッグするときのCtrl/Yの使用

デバッグ・セッション中にプログラムの実行やデバッガ・コマンドに割り込むには,Ctrl/C を押すのが望ましい方法です。Ctrl/C を押せば制御はデバッガに戻りますが,Ctrl/Y を押せば制御は DCL レベルに戻ります。

Ctrl/Y を押してタスク・デバッグ・セッションに割り込むと,DEBUG コマンドを使用して DCL レベルでデバッガを開始するときに問題が生じることがあります。そのような場合は,メイン・プログラムのソース・コードの先頭に次の 2 行を挿入して,Compaq Ada の定義済みパッケージCONTROL_C_INTERCEPTIONの名前を指定してください。


with CONTROL_C_INTERCEPTION; 
pragma ELABORATE(CONTROL_C_INTERCEPTION); 

このパッケージについての詳しい説明は,Comapq Ada のマニュアルを参照してください。


前へ 次へ 目次 索引