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

印刷ビューの終了

更新: 2015 年 1 月
 
 

イベント管理

イベント管理は、デバッグ中のプログラムで特定のイベントが発生したときに特定のアクションを実行する、dbx の一般的な機能です。

イベントハンドラ

イベント管理は ハンドラの概念に基づきます。この名前はハードウェアの割り込みハンドラからきたものです。各イベント管理コマンドは一般にハンドラを作成し、それは イベント指定と一連の副作用アクションで構成されます。(イベント指定の設定参照)。イベント指定は、ハンドラを発生させるイベントを指定します。

イベントが発生し、ハンドラが引き起こされると、イベント指定に含まれる任意の修飾子に従って、ハンドラはイベントを評価します (イベント指定修飾子参照)。修飾子によって課された条件にイベントが適合すると、ハンドラの関連アクションが実行されます (つまり、ハンドラが起動します)。

プログラムイベントを dbx アクションに対応付ける例は、特定の行にブレークポイントを設定するものです。

ハンドラを作成するもっとも汎用的な形式は、when コマンドを使用することです。

when event-specification {action; ... }

この章の例では、when に関してコマンド (stopstepignore など) を書く方法を示します。これらの例は、when とその配下にある「ハンドラ」メカニズムの柔軟性を示すものですが、常に同じ働きをするとはかぎりません。

イベントハンドラの作成

イベントハンドラを作成するには、when コマンド、stop コマンド、trace コマンドを使用します。(詳細については、when コマンドstop コマンド、および trace コマンドを参照)。

共通の when 構文は、stop を使用して簡単に表現できます。

when event-specification { stop -update; whereami; }

event-specification は、イベント管理コマンド stopwhentrace で、目的のイベントを指定するために使用します (イベント指定の設定を参照)。

trace コマンドのほとんどは、when コマンド、ksh 機能、イベント変数を使用して手動で作成することができます。これは、スタイル化されたトレーシング出力を希望する場合、特に有益です。

すべてのコマンドは、ハンドラ ID (hid) と呼ばれる番号を返します。事前定義変数 $newhandlerid を介してこの番号にアクセスすることができます。

イベントハンドラの操作

次のコマンドを使用して、イベントハンドラを操作することができます。各コマンドの詳細については、それぞれのセクションを参照してください。

表 B-1  イベントハンドラの操作
コマンド
説明
詳細情報
status
ハンドラを一覧表示します
status コマンドを参照してください
delete
一時ハンドラを含むすべてのハンドラを削除します
delete コマンドを削除してください
clear
ブレークポイントの位置に基づいてハンドラを削除します
clear コマンドを参照してください
handler –enable
ハンドラを有効にします
handler コマンドを参照してください
handler –disable
ハンドラを無効にします
handler コマンドを参照してください
cancel
シグナルを取り消し、プロセスが続行できるようにします
cancel コマンドを参照してください

イベントカウンタの使用

イベントハンドラには、カウント制限を保持するトリップカウンタがあります。イベントが発生するたびにカウンタをインクリメント (1 つ増加) し、ハンドラに関連付けられたアクションが実行されるのは、カウントが制限値に達したときのみで、その時点でカウンタは自動的に 0 にリセットされます。デフォルトの制限値は 1 です。プロセスを再実行する際は常に、すべてのイベントカウンタがリセットされます。

カウント制限を設定するには、stop コマンド、when コマンド、trace コマンドで –count 修飾子を使用します。このほか、handler コマンドを使用して、個々のイベントハンドラを操作できます。

handler [ -count | -reset ] hid new-count new-count-limit

イベントの安全性

dbx では、イベントメカニズムによって、豊富な種類のブレークポイントが用意されていますが、内部でも多くのイベントが使用されています。これらの内部イベントのいくつかで停止することによって、dbx の内部の動作を簡単に中断することができます。さらに、これらの場合の処理状態を変更すると、中断できる機会が増えます。Appendix A, プログラム状態の変更呼び出しの安全性を参照してください。

場合によっては、dbx は自身を保護して中断を妨げることがありますが、すべての場合ではありません。一部のイベントは下位レベルのイベントという観点で実装されています。たとえば、すべてのステップ実行は fault FLTTRACE イベントに基づきます。そのため、コマンド stop fault FLTTRACE を発行すると、ステップ実行が停止します。

デバッグに続く段階では、dbx はユーザーイベントを処理できません。これは、ユーザーイベントにより精密な内部統合が妨げられるからです。これらのフェーズに含まれるもの:

  • プログラムの起動時に rtld が実行された場合 (動的リンカーを参照)

  • プロセスの開始と終了時

  • fork() 関数と exec() 関数のあと (fork 機能後のプロセス追跡およびexec 機能後のプロセス追跡を参照)

  • dbx がユーザープロセスのヘッドを初期化する必要がある場合の呼び出し時 (proc_heap_init())

  • dbx がスタックのマップされたページを確実に利用できるようにする必要がある場合の呼び出し時 (ensure_stack_memory())

多くの場合、stop コマンドの代わりに when コマンドを使用して、情報を表示することができます。このコマンドを使用しない場合は、対話によって情報を取得する必要があります。

    dbx は次のようにして自身を保護します。

  • syncsyncrtld、および prog_new イベントに stop コマンドを許可しない

  • rtld ハンドシェーク時および前述のその他のフェーズで stop コマンドを無視する

例:

...SolBook linebreakstopped in munmap at 0xff3d503c 0xff3d503c: munmap+0x0004: ta %icc,0x00000008SolBook linebreak dbx76: warning: 'stop' ignored -- while doing rtld handshake

$firedhandlers 変数での記録を含む停止効果のみが無視されます。カウントやフィルタはアクティブなままになります。このような場合で停止させるには、event_safety 環境変数を off に設定します。

イベント指定の設定

イベント指定は、stop コマンド、stopi コマンド、when コマンド、wheni コマンド、trace コマンド、tracei コマンドで、イベントタイプとパラメータを表すために使用します。書式は、イベントタイプを表すキーワードとオプションのパラメータで構成されます。イベント指定の意味は、一般に 3 つすべてのコマンドで同じです。例外は付録 D のコマンドの説明に記載されています。

ブレークポイントイベント指定

ブレークポイントとは、アクションが発生する位置であり、その位置でプログラムは実行を停止します。このセクションでは、ブレークポイントイベントのイベント指定について説明します。

in イベント指定

in イベント指定の構文:

infunction

関数に入り、先頭行が実行される直前です。先行ログ後の最初の実行可能コードは、実際のブレークポイントの位置として使用されます。この行は、局所変数を初期化する行である場合があります。C++ のコンストラクタの場合、すべてのベースクラスのコンストラクタの実行後に実行されます。–instr 修飾子が使用された場合、それは関数の最初の命令が実行される直前です。function 仕様は、仮パラメータを含むことができるため、多重定義関数名、またはテンプレートインスタンスの指定に役立ちます。例:

 stop in mumble(int, float, struct Node *)

注 -  in function–in function 修飾子とを混同しないでください。

at イベント指定

at イベント指定の構文:

at[filename:]line-number

指定の行が実行される直前。filename を指定した場合は、指定したファイルの指定の行が実行される直前です。ファイル名には、ソースファイル名またはオブジェクトファイル名を指定します。引用符は不要ですが、ファイル名に特殊文字が含まれる場合は、必要な場合があります。指定の行がテンプレートコードに含まれる場合、ブレークポイントは、そのテンプレートのすべてのインスタンス上に置かれます。

特定のアドレスを指定することもできます。

ataddress-expression

指定のアドレスの指示が実行される直前。このイベントは stopi コマンドまたは –instr イベント修飾子でのみ使用できます。

infile イベント指定

infile イベント指定の構文:

infile filename

このイベントにより、ファイルで定義されたすべての関数にブレークポイントが設定されます。stop infile コマンドは、funcs –f filename コマンドと同じ関数のリストを繰り返します。

.h ファイル内のメソッド定義、テンプレートファイル、または .h ファイル内のプレーン C コード (regexp コマンドで使用される種類など) は、ファイルの関数定義に寄与する場合がありますが、これらの定義は除外されます。

指定されたファイル名が、オブジェクトファイルの名前の場合 (その場合、名前は .o で終了する)、ブレークポイントは、そのオブジェクトファイルで発生する関数すべてに設定されます。

stop infile list.h コマンドは、list.h ファイルで定義されたメソッドのすべてのインスタンスにブレークポイントを設定することはしません。そうするためには、inclass または inmethod のようなイベントを使用します。

fix コマンドは、関数をファイルから削除する、または追加する場合があります。stop infile コマンドは、ファイル内の関数のすべての古いバージョンと、将来追加されるすべての関数にブレークポイントを設定します。

ネストされた関数や Fortran ファイルのサブルーチンには、ブレークポイントは設定されません。

clear コマンドを使用して、infile イベントによって作成された組にある単一のブレークポイントを無効にできます。

infunction イベント指定

infunction イベント指定の構文:

infunctionfunction

この指定は、function という名前のすべての多重定義関数またはそれのすべてのテンプレートインスタンスに対する in function と同等です。

inmember イベント指定

inmember イベント指定の構文:

inmember function

この指定は inmethod イベント指定のエイリアスです。

inmethod イベント指定

inmember イベント指定の構文:

inmethod function

この指定は、すべてのクラスの function という名前のメンバーメソッドに対する in function と同等です。

inclass イベント指定

inclass イベント指定の構文:

inmember classname [-recurse | -norecurse]

この指定は、classname のメンバーであるが、classname のベースのメンバーではない、すべてのメンバー関数に対する in function と同等です。デフォルトは –norecurse です。–recurse が指定された場合、基底クラスが含まれます。

inobject イベント指定

inobject イベント指定の構文:

inobject object-expression [-recurse | -norecurse]

object-expression で示されるアドレスにある特定のオブジェクトに対して呼び出されたメンバー関数が呼び出されました。stop inobject ox はほぼ次と同じですが、inclass とは異なり、ox の動的タイプのベースが含まれます。–recurse はデフォルトです。–norecurse が指定された場合、基底クラスが含まれます。

stop inclass dynamic_type(ox) -if this==ox

データ変更イベント指定

このセクションでは、メモリーアドレスの内容へのアクセスや変更に関するイベントのイベント指定について説明します。

access イベント指定

access イベント指定の構文:

access mode address-expression [,byte-size-expression]

address-expression で指定されたメモリーがアクセスされたとき。

mode はメモリーのアクセス方法を指定します。有効な値は次のいずれかまたはすべての文字です。

r

指定したアドレスのメモリーが読み取られたことを示します。

w

メモリーへの書き込みが実行されたことを示します。

x

メモリーが実行されたことを示します。

さらに mode には、次のいずれかの文字も指定することができます。

a

アクセス後にプロセスを停止します (デフォルト)。

b

アクセス前にプロセスを停止します。

いずれの場合も、プログラムカウンタは副作用アクションの前後で違反している命令をポイントします。「前」と「後」は副作用を指しています。

address-expression は、その評価によりアドレスを生成できる任意の式です。記号式を指定すると、監視対象領域のサイズが自動的に推定されます。byte-size-expression を指定して、それをオーバーライドすることができます。さらに、シンボルを使用しない、型を持たないアドレス式を使用することもできますが、その場合はサイズが必須です。例:

stop access w 0x5678, sizeof(Complex)

access コマンドには、2 つの一致する領域が重複しない、という制限があります。


注 -  access イベント仕様は、modify イベント仕様の代替です。

change イベント指定

change イベント指定の構文:

change variable

variable の値は変更されました。change イベントは、次とほぼ同等です。

when step { if [ $last_value !=$[variable]] 
            then
                 stop
            else
                 last_value=$[variable]
            fi
          }

このイベントはシングルステップを使用して実装されます。パフォーマンスの向上のため、access イベントを使用してください。

最初に variable がチェックされると、変更が検出されない場合でも 1 つのイベントが発生します。この最初のイベントによって variable の最初の値にアクセスできるようになります。あとから検出された variable の値への変更によって別のイベントが発生します。

cond イベント指定

cond イベント指定の構文:

cond condition-expression

condition-expression で示された条件は true に評価されます。condition-expression には任意の式を使用できますが、整数型に評価されなければなりません。cond イベントは次の stop コマンドとほぼ同等です。

stop step -if conditional-expression

システムイベント指定

このセクションでは、システムイベントのイベント指定について説明します。

dlopen および dlclose イベント指定

dlopen() および dlopen() イベント指定の構文:

dlopen [ lib-path ]
dlclose [ lib-path ]

システムイベントは、dlopen() の呼び出しまたは dlclose() の呼び出しが成功したあとに発生します。dlopen() の呼び出しまたは dlclose() の呼び出しにより、複数のライブラリがロードされることがあります。これらのライブラリのリストは、事前定義済み変数 $dllist でいつでも入手できます。$dllist の中の最初のシェルの単語は + (プラス記号) または - (マイナス記号) で、ライブラリのリストに追加されているか、削除されているかを示します。

lib-path は、該当する共有ライブラリの名前です。これを指定した場合、そのライブラリが読み込まれたり、読み込みが取り消されたりした場合にだけイベントが起動します。その場合、$dlobj にライブラリの名前が格納されます。また、$dllist も利用できます。

lib-path/ で始まる場合は、パス名全体が比較されます。それ以外の場合は、パス名のベースだけが比較されます。

lib-path を指定しない場合、イベントは任意の dl 動作があるときに必ず起動します。$dlobj は空になりますが、$dllist は有効です。

fault イベント指定

fault イベント指定の構文:

fault fault

fault イベントは、指定された障害が検出されたときに発生します。障害は、アーキテクチャー依存です。dbx に認識される一連の障害を次のリストに示し、proc(4) マニュアルページで定義しています。

FLTILL

不正命令

FLTPRIV

特権付き命令

FLTBPT*

ブレークポイントトラップ

FLTTRACE*

トレーストラップ (ステップ実行)

FLTACCESS

メモリーアクセス (境界合わせなど)

FLTACCESS

メモリーアクセス (境界合わせなど)

FLTBOUNDS

メモリー境界 (無効なアドレス)

FLTIOVF

整数オーバーフロー

FLTIZDIV

整数ゼロ除算

FLTPE

浮動小数点例外

FLTSTACK

修復不可能なスタックフォルト

FLTPAGE

回復可能なページフォルト

FLTWATCH*

ウォッチポイントトラップ

FLTCPCOVF

CPU パフォーマンスカウンタオーバーフロー


注 -  FLTBPTFLTTRACE、および FLTWATCH は、dbx でブレークポイント、ステップ実行、ウォッチポイントを実装するために使われるため、処理されません。

これらの障害は、/sys/fault.h から抜粋されています。fault には上に挙げたいずれかを大文字または小文字、FLT- 接頭辞を付けるか付けないで指定するか、または実際の数値コードを指定できます。


注 -  fault イベントは、Linux プラットフォームでは使用できません。

lwp_exit イベント指定

lwp_exit イベント指定の構文:

lwp_exit

lwp_exit イベントは、lwp が終了したときに発生します。$lwp には、イベントハンドラの継続時間中に終了した LWP (軽量プロセス) の ID が含まれます。


注 -  lwpexit イベントは、Linux プラットフォームでは使用できません。

sig イベント指定

sig イベント指定の構文:

sigsignal

sig signal イベントは、デバッグ中のプログラムにシグナルが初めて送られたときに、発生します。signal は、10 進数、または大文字、小文字のシグナル名のいずれかです。接頭辞はオプションです。このイベントは、catch コマンドおよび ignore コマンドからは完全に独立しています。ただし、catch コマンドは次のように実装することができます。

function simple_catch {
    when sig $1 {
            stop;
            echo Stopped due to $sigstr $sig
            whereami
    }
}

注 -  sig イベントを受け取った時点では、プロセスはまだそれを見ることができません。指定の信号を持つプロセスを継続する場合のみ、その信号が転送されます。

または、サブコードでシグナルを指定することができます。sig イベント指定のこのオプションの構文:

sigsignal sub-code

指定の sub-code を持つ指定の信号が child に初めて送られたとき、sig signalsub-code イベントが発生します。シグナルと同様に、sub-code は 10 進数として、大文字または小文字で指定することができます。接頭辞はオプションです。

sysin イベント指定

sysin イベント指定の構文:

sysincode|name

指定されたシステムコールが起動された直後で、プロセスがカーネルモードに入ったとき。

dbx でサポートされるシステムコールの概念は、/usr/include/sys/syscall.h に列挙されるように、カーネルへのトラップによって提供されるものです。

この概念は、ABI のシステムコールの概念とは違います。ABI のシステムコールの一部は部分的にユーザーモードで実装され、非 ABI のカーネルトラップを使用します。ただし、一般的なシステムコールのほとんど (シグナル関係は除く) は syscall.h と ABI で共通です。


注 -  sysin イベントは、Linux プラットフォームでは使用できません。

/usr/include/sys/syscall.h 内のカーネルシステムコールトラップのリストは、Oracle Solaris OS のプライベートインタフェースの一部であり、リリースによって異なります。dbx が受け付けるトラップ名 (コード) およびトラップ番号のリストは、dbx がサポートするバージョンの Solaris OS によってサポートされているすべてを含みます。dbx によってサポートされている名前が特定のリリースの Solaris OS のそれらと正確に一致することはありえないため、syscall.h 内の一部の名前は使用できない場合があります。すべてのトラップ番号 (コード) は dbx で受け入れられ、予測どおりに動作しますが、既知のシステムコールトラップに対応しない場合は、警告が発行されます。

sysout イベント指定

sysout イベント指定の構文:

sysoutcode|name

指定されたシステムコールが終了し、プロセスがユーザーモードに戻る直前。


注 -  sysout イベントは、Linux プラットフォームでは使用できません。

sysin | sysout イベント指定

引数がないときは、すべてのシステムコールがトレースされます。ここで、modify イベントや RTC (実行時検査) などの特定の dbx は、子プロセスにその目的でシステムコールを引き起こすことがあることに注意してください。トレースした場合にそのシステムコールの内容が示されることがあります。

実行進行状況イベント仕様

このセクションでは、実行進行状況に関するイベントのイベント指定について説明します。

exit イベント指定

exit イベント指定の構文:

exitexitcode

exit イベントは、プロセスが終了したときに発生します。

next イベント指定

next イベントは、ステップインしない関数を除いて、step イベントと似ています。

returns イベント指定

returns イベントは、現在アクセスされている関数の戻りポイントにあるブレークポイントです。表示されている関数を使用するのは、いくつかの up を行なったあとに returns イベント指定を使用できるようにするためです。通常の returns イベントは常に一時イベント (–temp) で、動作中のプロセスが存在する場合にだけ作成できます。

returns イベント指定の構文:

returnsfunction

returns function イベントは、特定の関数がその呼び出し場所に戻るたびに実行されます。これは一時イベントではありません。戻り値は示されませんが、SPARC プラットフォームでは $o0、Intel プラットフォームでは $eax を使用して、必須戻り値を調べることができます。

  • SPARC ベースのシステム – $o0

  • x86 ベースのシステム – $eax

  • x64 ベースのシステム – $rax、$rdx

このイベントは、次のコードとほとんど同じ働きをします。

when in func { stop returns; }

step イベント指定

step イベントは、ソース行の最初の命令が実行されたときに発生します。たとえば、次のコマンドで簡単なトレースを取得できます。

when step { echo $lineno: $line; }; cont

step イベントを有効にするということは、次に cont コマンドが使用されるときに自動的にステップ実行できるように dbx に命令することと同じです。


注 -  step (および next) イベントは一般的なステップコマンド終了時に発生しません。step コマンドは step イベントに関して、大ざっぱに次のように実装します。alias step="when step -temp { whereami; stop; }; cont"

throw イベント指定

throw イベントの構文:

throw [type | –unhandled | –unexpected]

throw イベントは、アプリケーションによって、処理されないか、予期しない例外がスローされるたびに発生します。

throw イベントで例外のタイプが指定されている場合、そのタイプの例外だけが throw イベントを発生させます。

–unhandled オプションが指定されている場合、例外を示す特殊な例外タイプがスローされますが、それに対してハンドラが存在しません。

–unexpected オプションが指定されている場合、例外を示す特殊な例外タイプはそれをスローした関数の例外指定を満たしていません。

追跡されたスレッドイベント指定

次のセクションでは、追跡されたスレッドのイベント指定について説明します。

omp_barrier イベント指定

omp_barrier イベント指定は、追跡されたスレッドがバリアに入るか、出るタイミングです。type (explicit または implicit になる) と、state (enterexit、または all_entered になる) を指定できます。デフォルトは explicit all_entered です。

omp_taskwait イベント指定

omp_taskwait イベント指定は、追跡されたスレッドが taskwait に入るか、出るタイミングです。state を指定でき、これは enter または exit になります。デフォルトは exit です。

omp_ordered イベント指定

omp_ordered イベント指定は、追跡されたスレッドが Ordered 領域に入るか、出るタイミングです。state を指定でき、これは beginenter、または exit になります。デフォルトは enter です。

omp_critical イベント指定

omp_critical イベント指定は、追跡されたスレッドがクリティカル領域に入るか、出るタイミングです。

omp_atomic イベント指定

omp_atomic イベント指定は、追跡されたスレッドが不可分領域に入るか、出るタイミングです。state を指定でき、これは begin または exit になります。デフォルトは begin です。

omp_flush イベント指定

omp_flush イベント指定は、追跡されたスレッドが明示的なフラッシュ領域に入るか、出るタイミングです。

omp_task イベント指定

omp_task イベント指定は、追跡されたスレッドがタスク領域に入るか、出るタイミングです。state を指定でき、これは createstart、または finish になります。デフォルトは start です。

omp_master イベント指定

omp_master イベント指定は、追跡されたスレッドがマスター領域に入るか、出るタイミングです。

omp_single イベント指定

omp_single イベント指定は、追跡されたスレッドが Single 領域に入るタイミングです。

その他のイベント指定

このセクションでは、その他のタイプのイベントのイベント指定について説明します。

attach イベント指定

attach イベントは、dbx がプロセスに正常に接続したタイミングです。

detach イベント指定

detach イベントは dbx がデバッグ中のプログラムから正常に切り離されたタイミングです。

lastrites イベント指定

    lastrites イベントは、デバッグ中のプロセスが終了する直前のタイミングです。これは次の理由によって発生する可能性があります。

  • _exit(2) システムコールが、明示的な呼び出し経由か、または main() の戻り時に呼び出された。

  • 終了シグナルが送信されようとするとき。

  • dbx コマンド kill によってプロセスが強制終了されつつあるとき。

プロセスの最終段階は、必ずではありませんが通常はこのイベントが発生したときに利用可能になり、プロセスの状態を確認することができます。このイベントのあとにプログラムの実行を再開すると、プロセスは終了します。


注 -  lastrites イベントは、Linux プラットフォームでは使用できません。

proc_gone イベント指定

proc_gone イベントは dbx がデバッグ対象のプロセスに関連付けられなくなったときに発生します。事前定義済み変数 $reason は、signalexitkill、または detach になります。

prog_new イベント指定

prog_new イベントは、follow exec の結果として新しいプログラムがロードされたときに発生します。


注 -  このイベントのハンドラは常に存在しています。

stop イベント指定

stop イベントは、特に stop ハンドラへの応答として、ユーザーがプロンプトを受け取るなど、プロセスが停止するたびに発生します。次に例を示します。

display x
when stop {print x;}

sync イベント指定

sync イベントは、デバッグ中のプロセスが exec() で実行された直後に発生します。a.out で指定されたメモリーはすべて有効で存在しますが、あらかじめ読み込まれるべき共有ライブラリはまだ読み込まれていません。たとえば printfdbx に認識されていますが、まだメモリーにはマップされていません。

stop コマンドにこのイベントを指定しても期待した結果は得られません。when コマンドに指定してください。


注 -  sync イベントは、Linux プラットフォームでは使用できません。

syncrtld イベント指定

syncrtld イベントは、sync、またはデバッグ中のプロセスがまだ共有ライブラリを処理していない場合は attach のあとに発生します。これは、動的リンカーの起動コードが実行され、プリロード済みのすべての共有ライブラリのシンボルテーブルがロードされたあと、ただし、.init セクション内のコードが実行される前に実行します。

stop コマンドにこのイベントを指定しても期待した結果は得られません。when コマンドに指定してください。

thr_create [thread-ID] イベント指定

thr_create イベントは、スレッドまたは指定したスレッド ID を持つスレッドが作成されたときに発生します。たとえば、次の stop コマンドでスレッド ID t@1 はスレッド作成を示しますが、スレッド ID t@5 は作成済みスレッドを示しています。

stop thr_create t@5 -thread t@1

thr_exit イベント指定

thr_exit イベントは、スレッドが終了したときに発生します。指定したスレッドの終了を取り込むには、次のように stop コマンドで -thread オプションを使用します。

stop thr_exit -thread t@5

timer イベント指定

timer イベントの構文:

timerseconds

timer イベントは、デバッグ中のプログラムが seconds 秒間実行されたときに発生します。このイベントで使用されるタイマーは、collector コマンドで共有されます。解像度はミリ秒であるため、の浮動小数点値 (0.001 など) が使用可能です。

イベント指定修飾子

イベント指定のため修飾子は、ハンドラの追加属性を設定します。もっとも一般的な種類はイベントフィルタです。修飾子はイベント指定のキーワードのあとに指定しなければなりません。修飾子はダッシュ ( -) から始まります。各修飾子の構成は次のとおりです。

-if 修飾子

-if 修飾子の構文:

-ifcondition

イベント仕様で指定されたイベントが発生したとき、条件が評価されます。イベントは、条件が非ゼロと評価された場合にだけ発生すると考えられます。

–if 修飾子が、in または at などの 1 つだけのソース位置が関連付けられたイベントで使用された場合、condition はその位置に対応するスコープで評価されます。そうでない場合は、必要なスコープによって正しく修飾する必要があります。

マクロ展開は、print コマンドと同じ規約に従った条件で実行されます。

-resumeone 修飾子

–resumeone 修飾子は、マルチスレッドプログラムのイベント指定で、-if 修飾子とともに使用して、条件に関数呼び出しが含まれている場合に 1 つのスレッドのみを再開させることができます。詳細については、条件付きフィルタによるブレークポイントの修飾を参照してください。

-in 修飾子

-in 修飾子の構文:

-infunction

イベントは指定した関数の最初の命令に達したときから、関数が戻るときまでの間に発生した場合にのみトリガーします。関数の再帰は無視されます。

-disable 修飾子

–disable 修飾子は無効状態でハンドラを作成します。

-count n, -count infinity 修飾子

-count 修飾子の構文:

-countn

または

-count infinity

–count n および -count infinity 修飾子は、0 からのハンドラカウントを持ちます (イベントカウンタの使用を参照)。イベントが発生するたび、n に達するまでカウントはインクリメントします。一度それが生じると、ハンドラはファイアし、カウンタはゼロにリセットされます。

プログラムが実行または再実行されると、すべてのイベントのカウントがリセットされます。より具体的に言えば、カウントは sync イベントが発生するとリセットされます。

カウントは debug –r コマンド (debug コマンドを参照) または attach –r コマンド (attach コマンドを参照) を使用して新しいプログラムのデバッグを開始したときにリセットされます。

-temp 修飾子

-temp 修飾子は一時ハンドラを作成します。イベントが発生すると、一時イベントは削除されます。デフォルトではハンドラは、一時イベントではありません。ハンドラが計数ハンドラ (-count が指定されたイベント) の場合はゼロに達すると自動的に破棄されます。

一時ハンドラをすべて削除するには delete -temp を実行します。

-instr 修飾子

-instr 修飾子はハンドラを命令レベルで動作させます。これにより、ほとんどの ' i' で始まるコマンドは不要となります。この修飾子は、イベントハンドラの 2 つの面を修飾します。

  • 出力されるどのメッセージもソースレベルの情報ではなく、アセンブリレベルを示す。

  • イベントの細分性が命令レベルになる。たとえば step –instr は、命令レベルのステップ実行を意味する。

-thread 修飾子

-thread 修飾子の構文:

-threadthread-ID

-thread 修飾子はイベントを発生させたスレッドが異なるスレッド ID に一致する場合にのみ、アクションが実行されることを意味します。プログラムが次から次に実行されるうちに、目的とする特定のスレッドに、異なるスレッド ID が割り当てられることがあります。

-lwp 修飾子

-lwp 修飾子の構文:

-lwplwp-ID

-lwp 修飾子はイベントを発生させたスレッドが lwp-ID に一致する場合にのみ、アクションが実行されることを意味します。イベントを発生させたスレッドが lwp-ID と一致する場合にのみ、アクションが実行されます。プログラムが次から次に実行されるうちに、目的とする特定のスレッドに、異なる lwp-ID が割り当てられることがあります。

-hidden 修飾子

-hidden 修飾子は 通常の status コマンドでハンドラを非表示にします。隠されたハンドラを表示するには、status –h を使用してください。

-perm 修飾子

通常、すべてのハンドラは、新しいプログラムが読み込まれると廃棄されます。–perm 修飾子を使用すると、デバッグセッション間でハンドラが維持されます。delete コマンド単独では、永続ハンドラは削除されません。永続ハンドラを削除するには、delete –p を使用してください。

解析とあいまいさ

イベント指定と修飾子のための構文はキーワードドリブンで、ksh 規則に基づきます。すべてのものがスペースで区切られた単語に分割されます。

下位互換性のため、式の中には空白を含むことができます。そのため、式の内容があいまいになることがあります。たとえば、次の 2 つのコマンドがあるとします。

when a -temp
when a-temp

最初の例では、アプリケーションで temp という名前の変数が使用されていても、dbx 構文解析プログラムは –temp を修飾子としてイベント指定を解釈します。下の例では、a-temp がまとめて言語固有の式解析プログラムに渡され、a および temp という変数がない場合、エラーが発生します。オプションを括弧で囲むことにより、解析を強制できます。

事前定義済み変数の使用

特定の読み取り専用の ksh 事前定義済み変数が用意されています。次の表に示す変数は常に有効です。

変数
定義
$ins
現在の命令の逆アセンブル
$lineno
現在の行番号 (10 進数)
$vlineno
現在の表示行番号 (10 進数)
$line
現在の行の内容
$func
現在の関数の名前
$vfunc
現在の表示関数の名前
$class
$func が所属するクラスの名前
$vclass
$vfunc が所属するクラスの名前
$file
現在のファイルの名前
$vfile
現在表示しているファイルの名前
$loadobj
現在のロードオブジェクトの名前
$vloadobj
現在表示している現在のロードオブジェクトの名前
$scope
逆引用符表記での現在の PC のスコープ
$vscope
現在表示している逆引用符表記での PC のスコープ
$funcaddr
$func のアドレス (16 進数)
$caller
$func を呼び出している関数の名前
$dllist
dlopen イベントまたは dlclose イベントのあと、ロードされた、またはアンロードされた直後のロードオブジェクトのリストが格納されます。dllist の先頭の単語は、dlopen または dlclose のどちらが発生したかによる + (プラス記号) または - (マイナス記号) です。
$newhandlerid
最後に作成されたハンドラの ID。この変数は、ハンドラを削除するコマンドのあとの未定義の値です。ハンドラを作成した直後に変数を使用します。dbx では、複数のハンドラを作成する 1 つのコマンドに対してすべてのハンドラ ID を取り込むことはできません。
$firedhandlers
停止の原因となった最近のハンドラ ID のリストです。リスト上のハンドラは、status コマンドの出力に * (アスタリスク) でマークされます。
$proc
現在デバッグ中のプロセスの ID
$lwp
現在の LWP の ID。
$thread
現在のスレッドの ID
$newlwp
新しく作成された LWP の ID。
$newthread
新しく作成されたスレッドの ID。
$prog
デバッグ中のプログラムの絶対パス名
$oprog
$prog の前の値で、これは exec() のあとにデバッグしていたものに戻るために使用され、このときにプログラムのフルパス名は - (ダッシュ) に戻ります。$prog がフルパス名に展開され、$oprog がコマンド行または debug コマンドに指定されているプログラムパスを含みます。exec() が 2 回以上呼び出されると、オリジナルのプログラムには戻れません。
$exec32
dbx バイナリが 32 ビットの場合は true です。
$exitcode
プログラムの最後の実行ステータスを終了します。この値は、プロセスが実際には終了していない場合、空文字列になります。
$booting
イベントがブートプロセス中に発生すると、true に設定されます。新しいプログラムは、デバッグされるたびに、共有ライブラリのリストと位置を確認できるよう、まず実行されます。プロセスはそのあと終了します。このシーケンスは「ブート」と呼ばれます。
ブートが起こっても、イベントはすべて使用可能です。この変数は、たとえばデバッグの実行中に発生する sync および syncrtld イベントと、通常の実行中に発生するイベントを区別するために使用します。
$machtype
プログラムがロードされた場合、そのマシンタイプ sparcv8sparcv8+sparcv9、または intel を返します。そうでない場合、unknown を返します。
$datamodel
プログラムがロードされた場合、そのデータモデル ilp32 または lp64 を返します。そうでない場合、unknown を返します。ロードしたばかりのプログラムのモデルを見つけるには、.dbxrc ファイルで次を使用します。
when prog_new -perm {
     echo machine: $machtype $datamodel;
} 

次の例に、whereami を実装できることを示します。

function whereami {
  echo Stopped in $func at line $lineno in file $(basename $file)
  echo "$lineno\t$line"
}

when コマンドに対して有効な変数

このセクションで説明する変数は、when コマンド本体内でのみ有効です。

$handlerid

本体の実行中、$handlerid は本体が属する when コマンドの ID です。次のコマンドは同等です。

when X -temp { do_stuff; }
when X  { do_stuff; delete $handlerid; }

when コマンドと特定のイベントに対して有効な変数

特定の変数は、以下の表に示すように、when コマンドの本体内および特定のイベントに対してのみ有効です。

表 B-2  sig イベントに固有の変数
変数
説明
$sig
イベントを発生させたシグナル番号
$sigstr
$sig の名前
$sigcode
適用可能な場合、$sig のサブコード
$sigcodestr
$sigcode の名前
$sigsender
必要であれば、シグナルの送信者のプロセス ID
表 B-3  exit イベントに固有の変数
変数
説明
$exitcode
_exit(2) または exit(3) に渡された引数の値、または main の戻り値
表 B-4  dlopen および dlclose イベントに有効な変数
変数
説明
$dlobj
dlopen または dlclose されたロードオブジェクトのパス名
表 B-5  sysin および sysout イベントに有効な変数
変数
説明
$syscode
システムコール番号
$sysname
システムコール名
表 B-6  proc_gone イベントに固有の変数
変数
説明
$reason
signalexitkill、または detach のいずれか
表 B-7  thr_create イベントに固有の変数
変数
説明
$newthread
新しく作成されるスレッドの ID (t@5 など)
$newlwp
新しく作成される LWP の ID (l@4 など)
表 B-8  access イベントに有効な変数
変数
説明
$watchaddr
アドレスが書き込まれたり、読みだされたり、実行されたりします。
$watchmode
次のいずれかです。r は読み込み、w は書き込み、x は実行。そのあとに次のいずれかが続きます。a は後、b は前。

イベントハンドラの例

このセクションでは、イベントハンドラの設定のいくつかの例を挙げます。

配列メンバーへのストアに対するブレークポイントを設定する

この例は、array[99] にデータ変更ブレークポイントを設定する方法を示しています。

(dbx) stop access w &array[99]
(2) stop access w &array[99], 4
(dbx) run
Running: watch.x2
watchpoint array[99] (0x2ca88[4]) at line 22 in file "watch.c"    
   22    array[i] = i;

単純なトレースを実行する

この例は、単純なトレースを実装する方法を示しています

(dbx) when step { echo at line $lineno; }

関数内にいる間ハンドラを有効にする

次の例に、関数内にいる間ハンドラを有効にする方法を示します。

<dbx> trace step -in foo

このコマンドは次と同等です。

    # create handler in disabled state
    when step -disable { echo Stepped to $line; }
    t=$newhandlerid    # remember handler id
    when in foo {
    # when entered foo enable the trace
    handler -enable "$t"
    # arrange so that upon returning from foo,
    # the trace is disabled.
    when returns { handler -disable "$t"; };
    }

実行された行の数を調べる

この例は、小さなプログラムで実行された行数を確認する方法を示しています。入力:

(dbx) stop step -count infinity     # step and stop when count=inf
(2) stop step -count 0/infinity
(dbx) run
...
(dbx) status
(2) stop step -count 133/infinity

プログラムは停止することなく、プログラムが終了します。実行された行の数は 133 です。このプロセスは非常に低速です。この方法が有効なのは、何度も呼び出される関数にブレークポイントを設定している場合です。

実行された命令の数をソース行で調べる

この例は、コードのある行で実行する命令数をカウントする方法を示しています。

(dbx) ...                        # get to the line in question
(dbx) stop step -instr -count infinity
(dbx) step ...
(dbx) status
(3) stop step -count 48/infinity # 48 instructions were executed

ステップ実行している行で関数呼び出しが行われる場合、最終的にそれらの呼び出しもカウントされます。step イベントの代わりに next イベントを使用すれば、そのような呼び出しはカウントされません。

イベント発生後にブレークポイントを有効にする

別のイベントが発生した場合のみ、ブレークポイントを有効にします。たとえば、プログラムが関数 hash で、ただし 1300 番目のシンボル検索の後にのみ、正しく実行しなくなった場合、次のブレークポイントを使用します。

(dbx) when in lookup -count 1300 {
    stop in hash
    hash_bpt=$newhandlerid
    when proc_gone -temp { delete $hash_bpt; }
}

注 -  $newhandlerid は、実行されたばかりの stop in コマンドを表しています。

replay 時にアプリケーションファイルをリセットする

この例では、アプリケーションで replay 時にリセットされる必要があるファイルを処理する場合、プログラムを実行するたびにこれを行うハンドラを書くことができます。

(dbx) when sync { sh regen ./database; }
(dbx) run < ./database...    # during which database gets clobbered
(dbx) save
...              # implies a RUN, which implies the SYNC event which
(dbx) restore       # causes regen to run

プログラムのステータスのチェック

この例は、プログラムの実行中にプログラムの場所をすばやく確認する方法を示しています。入力:

(dbx) ignore sigint
(dbx) when sig sigint { where; cancel; }

次に、^C を発行して、プログラムを停止しないでそのスタックトレースを調べます。

この例は、基本的にコレクタ側の標本モードで実行することです (これだけではありません)。^C が使われているため、プログラムに割り込むには SIGQUIT (^\) を使用します。

浮動小数点例外の捕獲

次の例に、IEEE アンダーフローなど、特定の浮動小数点例外のみを捕獲する方法を示します。

(dbx) ignore FPE               # disable default handler
(dbx) help signals | grep FPE  # can’t remember the subcode name
...
(dbx) stop sig fpe FPE_FLTUND
...

ieee ハンドラを有効にする詳細については、FPE シグナルのトラップ (Oracle Solaris のみ)を参照してください。