実行、ステップ、および続行に使用されるコマンド (run、rerun、next、step、および cont) は、プロセス制御コマンドと呼ばれます。「cont at コマンド」 で説明するイベント管理コマンドとともに使用すると、プログラムが dbx のもとで実行されるときに、その実行時の動作を管理できます。
この章の内容は次のとおりです。
プログラムを初めて dbx に読み込むと、dbx はそのプログラムの「メイン」ブロック (C、C++、および Fortran 90 の場合は main、Fortran 77 の場合は MAIN、Java コードの場合は main クラス) に移動します。dbx は続いて、ユーザーから出されるコマンドを待機します。ユーザーは、コード上を移動するか、イベント管理コマンドを使用できます。
プログラムを実行する前に、そのプログラムにブレークポイントを設定することもできます。
JavaTM コードと C JNI (Java Native Interface) コードまたは C++ JNI コードの混在するアプリケーションをデバッグする場合に、まだ読み込まれていないコードでブレークポイントを設定することができます。これらのコードへのブレークポイントの設定の詳細については、「ネイティブ (JNI) コードでブレークポイントを設定する」を参照してください。
プログラムの実行を開始するには、run コマンドを使用します。
dbx で引数を指定しないでプログラムを実行するには、次のように入力します。
(dbx) run |
任意でコマンド行の引数と入出力の切り替えを追加できます。この場合は、次のように入力します。
(dbx) run [arguments][ < input_file] [ > output_file] |
Java アプリケーションの入力および出力をリダイレクトすることはできません。
run コマンドの出力は、dbx を実行しているシェルに noclobber を設定した場合でも、既存ファイルを上書きします。
run コマンドそのものは、前の引数とリダイレクトを使用して、プログラムを実行します。詳細については、「run コマンド」を参照してください。rerun コマンドは、元の引数とリダイレクトなしでプログラムを実行します。詳細については、「rerun コマンド」を参照してください。
すでに動作中のプログラムをデバッグしなければならないことがあります。動作中のプロセスにデバッグ機能を接続しなければならないのは、次のような場合です。
動作中のサーバーをデバッグしたいが、停止させたくない
動作中の GUI プログラムをデバッグしたいが、再起動したくない
プログラムが無限ループに入っているかもしれないので、プログラムを停止させずにデバッグしたい
このような場合は、動作中のプログラムのプロセス ID (process_id) を引数として dbx debug コマンドに渡せば、そのプログラムに dbx を接続することができます。
デバッグを終了すると、detach コマンドが使用され、プロセスを終了することなく dbx の制御からプログラムを解放することができます。
動作中のプロセスに接続されているときに dbx を終了すると、dbx は終了前に暗黙的に切り離しを行います。
dbx とは関係なく実行されるプログラムへ dbx を接続するには、attach コマンドまたは debug コマンドを使用します。
すでに実行中のプロセスへ dbx を接続するには、次のように入力します。
(dbx) debug program_name process_id |
または
(dbx) attach process_id |
program_name を – (ダッシュ) で置換することができます。dbx は、プロセス ID と関連するプログラムを自動的に検索し、ロードします。
詳細については、「debug コマンド」と 「attach コマンド」を参照してください。
dbx が実行中でない場合は、次のように入力して dbx を開始します。
% dbx program_name process_id |
プログラムに dbx を接続すると、そのプログラムは実行を停止します。このプログラムは、dbx に読み込んだプログラムの場合と同様にして調べることができます。任意のイベント管理コマンドまたはプロセス制御コマンドを使用してデバッグできます。
既存のプロセスのデバッグ中に dbx を新規のプロセスに接続すると、次のようになります。
現在デバッグ中のプロセスを run コマンドを使用して開始すると、新規のプロセスに接続する前にプロセスが終了します。
現在のプロセスを attach コマンドを使用するか、またはコマンド行でプロセス ID を指定することによってデバッグを開始すると、新規のプロセスに接続する前に現在のプロセスから切り離されます。
dbx を接続しようとしているプロセスが、SIGSTOP、SIGTSTOP、 SIGTTIN、SIGTTOUT シグナルによって停止した場合、接続が成功し、次のようなメッセージが表示されます。
dbx76: warning: Process is stopped due to signal SIGSTOP
プロセスは検査可能ですが、プロセスを再開するためには、cont コマンドでプロセスに SIGCONT シグナルを送信する必要があります。
(dbx) cont -sig cont |
特定の例外がある接続済みプロセスで実行時チェック機能を使用できます。「接続されたプロセスへの RTC の使用」を参照してください。
プログラムのデバッグが終了したら、detach コマンドを使用して dbx をプログラムから切り離してください。プログラムは切り離すときに -stop オプションを指定しないかぎり、dbx とは独立して実行を再開します。
dbx の制御のもとで、プロセスを実行から切り離すには、次のように入力します。
(dbx) detach |
dbx が占有アクセスしているときにブロックされるほかの /proc ベースのデバッグツールを一時的に適用している間に、プロセスを切り離して停止状態にすることができます。たとえば、次のようにします。
(dbx) oproc=$proc # Remember the old process ID (dbx) detach -stop (dbx) /usr/proc/bin/pwdx $oproc (dbx) attach $oproc |
詳細については、「detach コマンド」を参照してください。
dbx は、next と step というステップ実行のための基本コマンドに加え、step コマンドの 2 つの変形である step up と step to をサポートします。next と step はともに、プログラムにソースの 1 行を実行させ、停止します。
実行される行に関数呼び出しが含まれる場合、next コマンドにより、呼び出しは実行され、次の行で停止します (呼び出しを「ステップオーバー」)。step コマンドは、呼び出された関数の最初の行で停止します (呼び出しへの「ステップ」)。
step up コマンドは、関数をステップ実行したあと、呼び出し元の関数へプログラムを戻します。
step to コマンドは、現在のソース行で指定されている関数にステップするか、関数が指定されていない場合は、現在のソース行のアセンブリコードにより最後に呼び出される関数にステップします。条件付の分岐により、関数の呼び出しが発生しないことがあります。また、現在のソース行で関数が呼び出されない場合もあります。このような場合、step to は現在のソース行をステップオーバーします。
next および step コマンドの詳細については、「next コマンド」と 「step コマンド」を参照してください。
指定された数のコード行をシングルステップするには、実行したいコードの行数 [n] を付けた dbx コマンド、next または step を使用します。
(dbx) next n |
または
(dbx) step n |
step_granularity 環境変数は、step コマンドおよび next コマンドにより、コードに対する単位を決定します (「dbx 環境変数の設定」を参照)。単位は文か行のどちらかです。
環境変数 step_events (「dbx 環境変数の設定」を参照) は、ステップ実行中にブレークポイントが使用可能であるかどうかを制御します。
環境変数 step_abflow は、dbx が異常制御フロー変更が発生しそうになっていることを検出したときに停止するかどうかを制御します (「dbx 環境変数の設定」を参照)。このような制御フロー変更は、siglongjmp() または longjmp() の呼び出し、あるいは例外の送出が原因で発生することがあります。
現在のソースコード行から呼び出された関数にステップインするには、step to コマンドを使用します。たとえば、関数 GetDiscount()() にステップインするには、次のように入力します。
step to GetDiscount |
最後に呼び出された関数にステップインするには、次のように入力します。
step to |
(dbx) cont |
cont コマンドには、派生関数の cont at line_number があります。これを使用すると、現在のプログラム位置の行以外の行を指定して、プログラムの実行を再開することができます。これにより、再コンパイルすることなく、問題を起こすことがわかっている 1 行または複数行のコードをスキップできます。
(dbx) cont at 124 |
行番号は、プログラムが停止しているファイルから計算される点に注意してください。指定した行番号は、関数のスコープ内になければなりません。
cont at line_number と assign とを組み合わせると、ある変数の値を正しく計算できない関数の呼び出しが含まれている行を実行しないようにすることができます。
cont at line_number で、その値を正しく計算できない関数の呼び出しが含まれている行を飛ばします。
プログラムが行 123 で停止したと想定します。行 123 は関数 how_fast() を呼び出します。この関数が変数 speed を正しく計算していません。speed の正しい値がわかっているため、speed に値を代入することができます。そのあと、how_fast() の呼び出しを飛ばして、プログラムの実行を 124 行目から継続します。
(dbx) assign speed = 180; cont at 124; |
詳細については、「cont コマンド」を参照してください。
cont コマンドを when ブレークポイントコマンドとともに使用すると、プログラムは 123 行目の実行を試みるたびに how_fast() の呼び出しを飛ばします。
(dbx) when at 123 { assign speed = 180; cont at 124;} |
when コマンドについての詳細は、次の節を参照してください。
プログラムが停止しているとき、dbx コマンド call を使用して関数を呼び出すことができます。このコマンドでは、被呼び出し側関数に渡す必要のあるパラメータの値を指定することもできます。
関数 (手続き) を呼び出すには、関数の名前を入力し、その引数を指定します。たとえば、次のようにします。
(dbx) call change_glyph(1,3) |
パラメータは省略できますが、関数名 function_name のあとには必ず括弧を入力してください。たとえば、次のようにします。
(dbx) call type_vehicle() |
call コマンドを使用して関数を明示的に呼び出したり、関数呼び出しを含む式を評価するか、stop in glyph -if animate() などの条件付修飾子を使用して、関数を暗黙的に呼び出すことができます。
C++ 仮想関数は、print コマンドや call コマンド (「print コマンド」または 「call コマンド」を参照) を使用するその他の関数、または関数呼び出しを実行するその他のコマンドと同様に呼び出すことができます。
関数が定義されているソースファイルが -g フラグでコンパイルされたものであるか、プロトタイプ宣言が現在のスコープで可視であれば、dbx は引数の数と型をチェックし、不一致があったときはエラーメッセージを出します。それ以外の場合、dbx は引数の数をチェックしません。
デフォルトでは、call コマンドが実行されるたびに、dbx は fflush(stdout) を自動的に呼び出し、入出力バッファーに格納されているすべての情報を出力します。 自動的なフラッシュをオフにするには、dbx 環境変数 output_auto_flush を off に設定してください。
C++ の場合、dbx はデフォルト引数と関数の多重定義も処理します。可能であれば、C++ 多重定義関数の自動解析が行われます。関数を特定できない場合は (関数が -g でコンパイルされていない場合など)、多重定義名のリストが表示されます。
call を使用すると、dbx は next のように動作し、被呼び出し側から戻ります。しかし、プログラムが被呼び出し側関数でブレークポイントにあたると、dbx はそのブレークポイントでプログラムを停止し、メッセージを表示します。ここで where コマンドを実行すると、dbx コマンドのレベルを起点として呼び出しが行われたことが示されます。
実行を継続すると、呼び出しは正常に戻ります。強制終了、実行、再実行、デバッグを行おうとすると、dbx は入れ子になったインタプリタから回復しようとするので、コマンドが異常終了します。異常終了したコマンドは再発行することができます。また、pop -c コマンドを使用して、すべてのフレームを最後の呼び出しまでポップ (解放) することもできます。
call または呼び出しを含む式を出力することによって、デバッグしているプロセスを呼び出すと、明示されない重大な障害が発生する可能性があります。次に、注意すべきいくつかの状況と、それらを回避する方法を示します。
呼び出しが無限ループに入る可能性があります。これは中断できますが、中断しないと、セグメント例外が発生します。多くの場合、pop -c コマンドを使用して、呼び出しの場所に戻ることができます。
マルチスレッドアプリケーションで呼び出しを行う場合、デッドロックを回避するためにすべてのスレッドが再開されるため、呼び出したスレッド以外のスレッドに影響がおよぶ可能性があります。
ブレークポイント条件で使用した呼び出しによって、イベント管理が混乱する可能性があります (「実行の再開」を参照)。
dbx によって呼び出される一部の呼び出しは「安全」に実行されます。通常の「Stopped with call to ...」ではなく、主にセグメント例外などの問題が発生した場合、dbx は次のように動作します。
すべての stop コマンドは、メモリーアクセスエラーの検出によって実行されたコマンドも含め、無視されます。
pop -c コマンドを自動的に発行して、呼び出しの場所に戻ります。
実行を継続します。
dbx が安全な呼び出しを実行するのは、次のような呼び出しです。
display コマンドによって出力される式の中で実行する呼び出し。失敗した呼び出しは、次のように表示されます。ic0->get _data() = <call failed>
このような失敗を診断するには、print コマンドを使用して、式を出力します。
print -p コマンドを使用する場合を除く、db_pretty_print()() 関数の呼び出し。
イベント条件式で使用する呼び出し。呼び出しが失敗した条件は false と評価されます。
pop コマンドの実行時にデストラクタを呼び出すための呼び出し。
すべての内部呼び出し。
dbx で実行中のプロセスは、Control +C (^C) を使用して停止できます。^C によってプロセスを停止すると、dbx は ^C を無視しますが、子プロセスはそれを SIGINT と見なして停止します。このプロセスは、それがブレークポイントによって停止しているときと同じように検査することができます。
^C によってプログラムを停止したあとに実行を再開するには、コマンド cont を使用します。実行を再開する場合、cont に修飾語 sig signal_name は必要ありません。cont コマンドは、保留シグナルをキャンセルしたあとで子プロセスを再開します。