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

第 5 章 プログラムの実行制御

実行、ステップ、および続行に使用されるコマンド (runrerunnextstep、および cont) は、プロセス制御コマンドと呼ばれます。cont at コマンド」で説明するイベント管理コマンドとともに使用すると、プログラムが dbx のもとで実行されるときに、その実行時の動作を管理できます。

この章の内容は次のとおりです。

dbx でプログラムを実行する

プログラムを初めて dbx に読み込むと、dbx はそのプログラムの「メイン」ブロック (C、C++、および Fortran 90 の場合は main、Fortran 77 の場合は MAIN、Java コードの場合は main クラス) に移動します。dbx は続いて、ユーザーから出されるコマンドを待機します。ユーザーは、コード上を移動するか、イベント管理コマンドを使用できます。

プログラムを実行する前に、そのプログラムにブレークポイントを設定することもできます。


注 –

Java コードと 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 コマンド」を参照してください。

動作中のプロセスに dbx を接続する

すでに動作中のプログラムをデバッグしなければならないことがあります。動作中のプロセスにデバッグ機能を接続しなければならないのは、次のような場合です。

このような場合は、動作中のプログラムのプロセス 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 を新規のプロセスに接続すると、次のようになります。

dbx を接続しようとしているプロセスが、SIGSTOPSIGTSTOP SIGTTINSIGTTOUT シグナルによって停止した場合、接続が成功し、次のようなメッセージが表示されます。

dbx76: warning: Process is stopped due to signal SIGSTOP

プロセスは検査可能ですが、プロセスを再開するためには、cont コマンドでプロセスに SIGCONT シグナルを送信する必要があります。


(dbx) cont -sig cont

特定の例外がある接続済みプロセスで実行時チェック機能を使用できます。「接続されたプロセスへの RTC の使用」を参照してください。

プロセスから dbx を切り離す

プログラムのデバッグが終了したら、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 は、nextstep というステップ実行のための基本コマンドに加え、step コマンドの 2 つの変形である step upstep to をサポートします。nextstep はともに、プログラムにソースの 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

プログラムを継続する

プログラムを継続するには、cont コマンドを使用します。


(dbx) cont

cont コマンドには、派生関数の cont at line_number があります。これを使用すると、現在のプログラム位置の行以外の行を指定して、プログラムの実行を再開することができます。これにより、再コンパイルすることなく、問題を起こすことがわかっている 1 行または複数行のコードをスキップできます。

指定の行でプログラムを継続するには、次のように入力します。


(dbx) cont at 124

行番号は、プログラムが停止しているファイルから計算される点に注意してください。指定した行番号は、関数のスコープ内になければなりません。

cont at line_numberassign とを組み合わせると、ある変数の値を正しく計算できない関数の呼び出しが含まれている行を実行しないようにすることができます。

Procedure特定の行からプログラムの実行を再開する

  1. assign コマンドを使用して変数に正しい値を代入します。

  2. 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 コマンドが実行されるたびに、dbxfflush(stdout) を自動的に呼び出し、入出力バッファーに格納されているすべての情報を出力します。 自動的なフラッシュをオフにするには、dbx 環境変数 output_auto_flushoff に設定してください。

C++ の場合、dbx はデフォルト引数と関数の多重定義も処理します。可能であれば、C++ 多重定義関数の自動解析が行われます。関数を特定できない場合は (関数が -g でコンパイルされていない場合など)、多重定義名のリストが表示されます。

call を使用すると、dbxnext のように動作し、被呼び出し側から戻ります。しかし、プログラムが被呼び出し側関数でブレークポイントにあたると、dbx はそのブレークポイントでプログラムを停止し、メッセージを表示します。ここで where コマンドを実行すると、dbx コマンドのレベルを起点として呼び出しが行われたことが示されます。

実行を継続すると、呼び出しは正常に戻ります。強制終了、実行、再実行、デバッグを行おうとすると、dbx は入れ子になったインタプリタから回復しようとするので、コマンドが異常終了します。異常終了したコマンドは再発行することができます。また、pop -c コマンドを使用して、すべてのフレームを最後の呼び出しまでポップ (解放) することもできます。

安全な呼び出し

call または呼び出しを含む式を出力することによって、デバッグしているプロセスを呼び出すと、明示されない重大な障害が発生する可能性があります。次に、注意すべきいくつかの状況と、それらを回避する方法を示します。

dbx によって呼び出される一部の呼び出しは「安全」に実行されます。通常の「Stopped with call to ...」ではなく、主にセグメント例外などの問題が発生した場合、dbx は次のように動作します。

dbx が安全な呼び出しを実行するのは、次のような呼び出しです。

Ctrl+C によってプロセスを停止する

dbx で実行中のプロセスは、Ctrl+C (^C) を使用して停止できます。^C によってプロセスを停止すると、dbx^C を無視しますが、子プロセスはそれを SIGINT と見なして停止します。このプロセスは、それがブレークポイントによって停止しているときと同じように検査することができます。

^C によってプログラムを停止したあとに実行を再開するには、コマンド cont を使用します。実行を再開する場合、cont に修飾語 sig signal_name は必要ありません。cont コマンドは、保留シグナルをキャンセルしたあとで子プロセスを再開します。