前へ | 次へ | 目次 | 索引 |
図 17-1 はタスク・スタックを示します。
SHOW TASK/FULL コマンドでは,選択した各タスクについての詳細情報が表示されます。例 17-7 には,Ada タスク例に対してこのコマンドを実行したときの出力が示されています。
例 17-7 ADAタスクに対してSHOW TASK/FULLを実行したときの表示例 |
---|
(1) task id pri hold state substate task object * %TASK 2 7 RUN TASK_EXAMPLE.MOTHER+4 (2) Waiting entry callers: Waiters for entry BOGUS: %TASK 4, type: CHILD (3) Task type: FATHER_TYPE Created at PC: TASK_EXAMPLE.%LINE 14+22 Parent task: %TASK 1 Start PC: TASK_EXAMPLE.FATHER_TYPE$TASK_BODY (4) Task control block: (5) Stack storage(bytes): Task value: 490816 RESERVED_BYTES: 10640 Entries: 3 TOP_GUARD_SIZE: 5120 Size: 1488 STORAGE_SIZE: 30720 (6) Stack addresses: Bytes in use: 456 Top address: 001EB600 Base address: 001F2DFC (7) Total storage: 47968 DBG> |
次の番号は,例 17-7 の番号に対応しています。
VAX システムでは,保護領域ページとして割り当てるバイト数は,Compaq Ada プラグマの TASK_STORAGEとMAIN_STORAGE に指定できる。デバッガにより表示される値は,割り当てられたバイト数である。プラグマの値は,ページ数が整数になるように,必要に応じて切り上げられる。これらのプラグマと上部記憶保護領域についての詳しい説明は,Compaq Ada のマニュアルを参照。
Alpha システムでは,保護領域ページとして割り当てるバイト数は,Compaq Ada プラグマの TASK_STORAGE に指定できる。デバッガにより表示される値は,割り当てられたバイト数である。プラグマの値は,ページ数が整数になるように,必要に応じて切り上げられる。これらのプラグマと上部記憶保護領域についての詳しい説明は,Compaq Ada のマニュアルを参照。
VAX システムでは,割り当てるバイト数は,T'STORAGE_SIZE 表現句か Ada プラグマの MAIN_STORAGE に指定する。デバッガにより表示される値は,割り当てられたバイト数である。指定した値は,ページ数が整数になるように,必要に応じて切上げられる。この表現句とプラグマおよびタスク起動用(作業用)記憶域についての詳しい説明は,Compaq Adaのマニュアルを参照。
AXP システムでは,割り当てるバイト数は,T'STORAGE_SIZE 表現句で指定する。デバッガにより表示される値は,割り当てられたバイト数である。指定した値は,ページ数が整数になるように,必要に応じて切上げられる。この表現句とプラグマおよびタスク起動用(作業用)記憶域についての詳しい説明は,Compaq Ada のマニュアルを参照。
SHOW TASK/STATISTICS コマンドでは,プログラム内のすべてのタスクについての統計情報が報告されます。例 17-8 は,VAX プロセッサで Ada タスキング・プログラム例に対して SHOW TASK/STATISTICS/FULL コマンドを実行したときの出力です。この情報により,プログラムの性能を測定できます。スケジューリング(コンテキスト・スイッチとも呼ぶ)の総数が多いほど,タスキング・オーバヘッドは大きくなります。
例 17-8 Adaタスクに対してSHOW TASK/STATISTICS/FULLを実行したときの表示例(VAX プロセッサの例) |
---|
task statistics Entry calls = 4 Accepts = 1 Selects = 2 Tasks activated = 3 Tasks terminated = 0 ASTs delivered = 4 Hibernations = 0 Total schedulings = 15 Due to readying a higher priority task = 1 Due to task activations = 3 Due to suspended entry calls = 4 Due to suspended accepts = 1 Due to suspended selects = 2 Due to waiting for a DELAY = 0 Due to scope exit awaiting dependents = 0 Due to exception awaiting dependents = 0 Due to waiting for I/O to complete = 0 Due to delivery of an AST = 4 Due to task terminations = 0 Due to shared resource lock contention = 0 DBG> |
デバッグ中にタスクの特性やタスキング環境を変更するには,次表の SET TASK コマンドを使用します。
コマンド | 機能 |
---|---|
SET TASK/ACTIVE | 指定されたタスクをアクティブ・タスクにする。POSIX Threads(OpenVMS Alpha システムまたは VAX システム)でも Ada(OpenVMS Alpha システム)でも動作しない(第 17.3.1 項 を参照)。 |
SET TASK/VISIBLE | 指定されたタスクを可視タスクにする(第 17.3.1 項 を参照)。 |
SET TASK/ABORT | 次に可能な機会にタスクを終了するように要求する。具体的な効果はそのときのイベント機能により異なる(言語依存)。Ada タスクの場合,これは abort 文の実行と同じである。 |
SET TASK/PRIORITY | タスクの優先順位を設定する。具体的な効果はそのときのイベント機能により異なる(言語依存)。 |
SET TASK/RESTORE | タスクの優先順位を復元する。具体的な効果はそのときのイベント機能により異なる(言語依存)。 |
SET TASK/[NO]HOLD | タスク・スイッチを制御する。タスク状態の遷移については 第 17.5.1 項 を参照。 |
SET TASK/TIME_SLICE | タイム・スライス値を制御するか,タイム・スライス機能を禁止する。VAX Ada のみでサポートされ,POSIX Threads ではサポートされていない(第 17.5.2 項 を参照)。 |
詳細については,SET TASK コマンドの説明を参照してください。
17.5.1 タスクの保留によるタスク・スイッチの制御
タスク・スイッチにより,プログラムのデバッグが複雑になります。SET TASK/HOLD コマンドを使用してタスクを保留すれば,あとでそのプログラムが実行可能になったときにそのタスクが移る状態を制限できます。
保留されたタスクは RUNNING 以外のいずれかの状態に移ります。しかし,必要であれば SET TASK/ACTIVE コマンドを使用して保留されたタスクを RUNNING 状態に移すことも可能です。
SET TASK/HOLD/ALL コマンドではアクティブ・タスク以外のすべてのタスクの状態が凍結されます。このコマンドを SET TASK/ACTIVE コマンドと併用すれば,指定した 1 つか複数のタスクの動作を観察できます。そのためには,STEP コマンドまたは GO コマンドによってそのアクティブ・タスクを実行し,SET TASK/ACTIVE コマンドを使用して実行を別のタスクに切り替えます。次に例を示します。
DBG> SET TASK/HOLD/ALL DBG> SET TASK/ACTIVE %TASK 1 DBG> GO . . . DBG> SET TASK/ACTIVE %TASK 3 DBG> STEP . . . |
タスクを保留する必要がなくなったら,SET TASK/NOHOLD コマンドを使用します。
17.5.2 タイム・スライス機能を使用するプログラムのデバッグ(VAX のみ)
タイム・スライス機能を使用するタスキング・プログラムのデバッグは複雑です。タイム・スライス機能によってタスクの相対的な動作が非同期になるからです。タイム・スライス機能を使用しない場合,タスクの実行はタスクの優先順位だけで決まります。タスク・スイッチは予測可能なので,実行のたびにプログラムの同じ動作を繰り返すことができます。タイム・スライス機能を使用する場合もタスクの優先順位によってタスク・スイッチが行われますが,指定期間は同じ優先順位の複数のタスクが交互に実行されます。したがって,タイム・スライス機能があれば各タスクは互いにいっそう独立して実行されるようになります。そのため,タイム・スライス機能を使用するプログラムは,実行するたびに同じ動作を繰り返さないことがあります。
SET TASK/TIME_SLICE=t コマンド(VAX Ada のみでサポート)を使用すれば,新しいタイム・スライスを指定したり,SET TASK/TIME_SLICE=0.0 と指定してタイム・スライス機能を禁止したりできます。したがって,タスキング・プログラムの実行を調整したり,タスクの実行順序に依存する問題を診断したりできます。
SET TASK/TIME_SLICE コマンドは,VAX Ada のみでサポートされており,POSIX Threads を使用した VAX Ada ではサポートされていません。サポートされていないコンテキストでコマンドを使用する場合,次のエラー・メッセージが出されます。
|
タイム・スライス機能とデバッガのウォッチポイントの実行とは,互いに影響を与えることに注意してください。ウォッチポイントを設定すると,タイム・スライス間隔値はデバッガにより自動的に 10.0 秒に増加されることがあります。タイム・スライス速度を遅くすることにより,発生を防げる問題があるからです。
17.6 実行の制御とモニタ
次の各項では,次の各機能の実行方法について説明します。
17.6.1 タスク依存およびタスク非依存のデバッガ・イベントポイントの設定
イベントポイント とは,デバッガに制御を戻すために使用できるイベントです。ブレークポイント,トレースポイント,ウォッチポイント,および STEP コマンドの終了はいずれもイベントポイントです。
タスク非依存イベントポイント は,プログラム内のいずれかのタスクの実行によって起動されます。そのイベントポイントの設定時にどのタスクがアクティブなのかは関係ありません。タスク非依存イベントポイントの指定には,行番号や名前などのアドレス式を使用するのが普通です。ウォッチポイントはすべて,タスク非依存イベントポイントです。次にタスク非依存イベントポイントの設定例を示します。
DBG> SET BREAK COUNTER DBG> SET BREAK/NOSOURCE %LINE 55, CHILD$TASK_BODY DBG> SET WATCH/AFTER=3 KEEP_COUNT |
タスク依存イベントポイント は,コマンド入力時にアクティブなタスクにしか設定できません。タスク依存イベントポイントは,その同じタスクがアクティブなときにしか起動されません。たとえば,STEP/LINE コマンドはタスク依存イベントポイントです。その他のタスクが同じソース行を実行してもそのイベントは起動されないことがあります。
次の修飾子を指定して SET BREAK, SET TRACE,または STEP コマンドを実行すれば,タスク依存イベントポイントが設定されます。
/BRANCH
/CALL
/INSTRUCTION
/LINE
/RETURN
/VECTOR_INSTRUCTION(VAX専用)
これらのコマンドでこれらの修飾子を使用しないで設定するイベントポイントおよび SET WATCH コマンドを使用して設定するイベントポイントは,タスク非依存になります。次にタスク依存イベントポイントの設定例を示します。
DBG> SET BREAK/INSTRUCTION DBG> SET TRACE/INSTRUCTION/SILENT DO(EXAMINE KEEP_COUNT) DBG> STEP/CALL/NOSOURCE |
通常はタスク非依存のイベントポイントに条件を設定して,タスク依存にすることができます。次に例を示します。
DBG> SET BREAK %LINE 11 WHEN(%ACTIVE_TASK=FATHER) |
17.6.2 POSIX Threads タスキング構造へのブレークポイントの設定
ブレークポイントをスレッド起動ルーチンに設定することは可能です。そのようなブレークポイントは,起動ルーチンの実行開始直前に検出されます。例 17-1 の場合は,この型のブレークポイントはたとえば次のように設定します。
DBG> SET BREAK worker_routine |
Ada タスクの場合とは異なり POSIX Threads タスクの場合は名前で本体を指定することはできませんが,起動ルーチンは似ています。
SET BREAK コマンドに WHEN 句を指定すれば,特定のスレッドの実行開始時点を確実にとらえることができます。次に例を示します。
DBG> SET BREAK worker_routine - _DBG> WHEN(%CALLER_TASK = %TASK 4) |
例 17-1 の場合,この条件付きブレークポイントは 2 番目のワーカ・スレッドがその起動ルーチンを開始するときに検出されます。
ブレークポイントの設定に適するその他の箇所には,条件待ち,結合,およびミューテクスのロックの直前と直後があります。そのようなブレークポイントの設定には,行番号かルーチン名を指定します。
17.6.3 Adaタスク本体,エントリ呼び出し,およびaccept文へのブレークポイントの設定
タスク本体にブレークポイントを設定するには,次のどちらかの構文に従ってタスク本体を指定します(第 17.3.2 項 を参照)。
task-type-identifier$TASK_BODY |
task-identifier$TASK_BODY |
たとえば,次のコマンドではタスク CHILD の本体にブレークポイントが設定されます。そのブレークポイントは,タスクの宣言部分の作成(タスクのアクティベーションとも呼ぶ)の直前に検出されます。
DBG> SET BREAK CHILD$TASK_BODY |
CHILD$TASK_BODY は,タスクが最初に実行する命令が置かれている箇所の名前です。ブレークポイントをある命令に設定するのは意味があることなので,この名前を指定します。しかし,SET BREAK コマンドにタスク・オブジェクトの名前(たとえば,CHILD)を指定してはなりません。タスク・オブジェクト名は,データ項目のアドレス(32 ビットのタスク値)を示します。整数オブジェクトにブレークポイントを設定するのは間違いであるように,タスク・オブジェクト名にブレークポイントを設定するのも間違いです。
エントリ呼び出し文と accept 文にブレークポイントかトレースポイントを設定すれば,呼ぶ側,呼ばれる側のタスクの実行をモニタできます。
Ada タスクのエントリ呼び出しは,サブプログラム呼び出しと同じではありません。タスク・エントリ呼び出しはキューに登録されるので,すぐ実行されるとは限らないからです。STEP コマンドを使用して実行をタスク・エントリ呼び出しに移しても,期待通りの結果が得られないことがあります。 |
ブレークポイントやトレースポイントの設定に適する箇所は,accept 文とその前後に数箇所あります。たとえば,RENDEZVOUS という同じエントリに 2 つの accept 文が使用されている次のプログラム・セグメントについて考えてみます。
8 task body TWO_ACCEPTS is 9 begin 10 for I in 1..2 loop 11 select 12 accept RENDEZVOUS do 13 PUT_LINE("This is the first accept statement"); 14 end RENDEZVOUS; 15 or 16 terminate; 17 end select; 18 end loop; 19 accept RENDEZVOUS do 20 PUT_LINE("This is the second accept statement"); 21 end RENDEZVOUS; 22 end TWO_ACCEPTS; |
この例では,次の箇所にブレークポイントかトレースポイントを設定できます。
accept 文かその前後にブレークポイントかトレースポイントを設定するためには,その行番号を指定します。たとえば,次のコマンドでは,前の例の最初の accept 文の先頭と本体にブレークポイントが設定されます。
DBG> SET BREAK %LINE 12, %LINE 13 |
accept 文の本体にブレークポイントかトレースポイントを設定するには,エントリ名も使用できます。その展開された名前を指定して,そのエントリが宣言されているタスク本体を示します。次に例を示します。
DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS |
同じエントリに 2 つ以上の accept 文がある場合,デバッガはそのエントリをオーバロードされた名前として扱います。デバッガからそのシンボルがオーバロードされていることを示すメッセージが発行されるので,ユーザは SHOW SYMBOL コマンドを使用して,デバッガによって割り当てられたオーバロードされた名前を表示しなければなりません。次に例を示します。
DBG> SHOW SYMBOL RENDEZVOUS overloaded symbol TEST.TWO_ACCEPTS$TASK_BODY.RENDEZVOUS overloaded instance TEST.TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__1 overloaded instance TEST.TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 |
オーバロードされた名前の後ろには,2 つの下線と整数が続きます。オーバロードされた名前についての詳しい説明は,デバッガのオンライン・ヘルプを参照してください(Help Language_Support Ada を入力します)。
オーバロードされた名前のどちらが特定の accept 文に対応しているかを知るためには,EXAMINE/SOURCE コマンドを使用します。次に例を示します。
DBG> EXAMINE/SOURCE TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__1 module TEST_ACCEPTS 12: accept RENDEZVOUS do DBG> EXAMINE/SOURCE TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 module TEST_ACCEPTS 19: accept RENDEZVOUS do |
次の例でブレークポイントが検出されると,呼び出しタスクが評価されます。シンボル %CALLER_TASK についての詳しい説明は,第 17.3.4 項 を参照してください。
DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 - _DBG> DO(EVALUATE %CALLER_TASK) |
次のブレークポイントが検出されるのは,呼び出しタスクが %TASK 2 のときだけです。
DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 - _DBG> WHEN(%CALLER_TASK = %TASK 2) |
呼び出しタスクが同じ accept 文に 2 回以上エントリ呼び出しを行う場合は,SHOW TASK/CALLS コマンドを使用することにより,そのエントリ呼び出しが実行されたソース行を表示できます。たとえば,次のように指定します。
DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 - _DBG> DO(SHOW TASK/CALLS %CALLER_TASK) |
前へ | 次へ | 目次 | 索引 |