プログラムをGDB配下で実行するには、 コンパイル時にデバッグ情報を生成する必要があります。 ユーザが選択した環境で、 必要に応じて引数を指定して、 GDBを起動することができます。 プログラムの入力元と出力先をリダイレクトすること、 既に実行中のプロセスをデバッグすること、 子プロセスを終了させることもできます。
プログラムを効率的にデバッグするためには、 そのプログラムのコンパイル時にデバッグ情報を生成する必要があります。 このデバッグ情報はオブジェクト・ファイルに格納されます。 この情報は、 個々の変数や関数の型、 ソース・コード内の行番号と実行形式コードのアドレスとの対応などを含みます。 デバッグ情報の生成を要求するには、 コンパイラの実行時に`-g'オプションを指定します。 多くのCコンパイラでは、 `-g'オプションと`-O'オプションを同時に指定することができません。 このようなコンパイラでは、 デバッグ情報付きの最適化された実行ファイルを生成することができません。 GNUのCコンパイラであるGCCは、 `-O'オプションの有無にかかわらず、 `-g'オプションが指定できます。 したがって、 最適化されたコードをデバッグすることが可能です。 プログラムをコンパイルするときには、 常に`-g'オプションを指定することをお勧めします。 自分のプログラムは正しいと思うかもしれませんが、 自分の幸運を信じて疑わないというのは無意味なことです。 `-g -O'オプションを指定してコンパイルされたプログラムをデバッグするときには、 オプティマイザがコードを再調整していることを忘れないでください。 デバッガは、 実際に存在するコードの情報を表示します。 実行されるパスがソース・ファイルの記述と一致していなくても、 あまり驚かないでください。 これは極端な例ですが、 定義されているが実際には使われていない変数を、 GDBは認識しません。 なぜなら、 コンパイラの最適化処理により、 そのような変数は削除されるからです。 命令スケジューリング機能を持つマシンなどでは、 `-g'を指定してコンパイルされたプログラムでは正しく動作することが、 `-g -O'を指定してコンパイルされたプログラムでは正しく動作しないということがあります。 `-g -O'を指定してコンパイルされたプログラムのデバッグで何かおかしな点があれば、 `-g'だけを指定してコンパイルしてみてください。 これで問題が解決するようであれば、 (再現環境と一緒に) 障害として私たちに報告してください。 古いバージョンのGNU Cコンパイラは、 デバッグ情報の生成のためのオプションの1つとして `-gg'をサポートしていました。 現在のGDBはこのオプションをサポートしていません。 お手元のGNU Cコンパイラにこのオプションがあるようであれば、 それは使わないでください。
run
r
run
コマンドを使用してください。
(VxWorks以外の環境では)
最初にプログラム名を指定する必要があります。
これには、
GDBへの引数を使用する方法
(GDBの起動・終了を参照)
と、
file
コマンドまたはexec-file
コマンドを使用する方法
(ファイルを指定するコマンドを参照)
とがあります。
プロセスをサポートする環境でプログラムを実行している場合、
run
コマンドは下位プロセスを生成し、
そのプロセスにプログラムを実行させます
(プロセスをサポートしていない環境では、
run
コマンドはプログラムの先頭アドレスにジャンプします)。
プログラムの実行は、
上位プロセスから受け取る情報によって影響されます。
GDBはこの情報を指定する手段を提供しています。
これは、
ユーザ・プログラムが起動される前に実行されていなければなりません
(ユーザ・プログラムの実行後にその情報を変更することも可能ですが、
その変更結果は、
次にプログラムを実行したときに初めて有効になります)。
この情報は、
4つに分類することができます。
run
コマンドへの引数として指定します。
ターゲット上でシェルが使用可能であれば、
引数を表現するのに通常使用する手法
(例えば、
ワイルドカード拡張や変数による代替など)
が利用できるよう、
シェルを経由して引数を渡します。
UNIXシステムでは、
SHELL
環境変数によって、
使用されるシェルを選択することができます。
ユーザ・プログラムの引数を参照してください。
set environment
コマンドと
unset environment
コマンドを使用して、
ユーザ・プログラムの実行に影響する環境の一部を変更することができます。
ユーザ・プログラムの環境を参照してください。
cd
コマンドで設定可能です。
ユーザ・プログラムの作業ディレクトリを参照してください。
run
コマンドのコマンド・ライン上で、
標準入力、
標準出力をリダイレクトすることも可能です。
また、
tty
コマンドによって別のデバイスを割り当てることも可能です。
ユーザ・プログラムの入出力を参照してください。
注意: 入出力のリダイレクトは機能しますが、
デバッグ中のプログラムの出力を、
パイプを使用して他のプログラムに渡すことはできません。
このようなことをすると、
GDBは誤って、
別のプログラムのデバッグを開始してしまうでしょう。
run
コマンドを実行すると、
ユーザ・プログラムはすぐに実行を始めます。
プログラムを停止させる方法については、
停止と継続を参照してください。
プログラムが停止すると、
print
コマンドまたはcall
コマンドを使用して、
プログラム内の関数を呼び出すことができます。
データの検査を参照してください。
GDBが最後にシンボル情報を読み込んだ後に、
シンボル・ファイルの修正タイムスタンプが変更されている場合、
GDBはシンボル・テーブルを破棄し再読み込みを行います。
この場合、
GDBは、
その時点におけるブレイクポイントの設定を保持しようと試みます。
ユーザ・プログラムへの引数は、
run
コマンドへの引数によって指定可能です。
それはまずシェルに渡され、
ワイルドカードの展開やI/Oのリダイレクトの後、
プログラムに渡されます。
SHELL
環境変数によって、
GDBの使用するシェルが指定されます。
SHELL
環境変数が定義されていないと、
GDBは/bin/sh
を使用します。
引数を指定せずに
run
コマンドを実行すると、
前回run
コマンドを実行したときの引数、
または、
set args
コマンドでセットされた引数が使用されます。
set args
set args
が引数なしで実行された場合、
run
コマンドは、
ユーザ・プログラムを引数なしで実行します。
一度プログラムに引数を指定して実行すると、
次にプログラムを引数なしで実行する唯一の方法は、
run
コマンドを実行する前に
set args
コマンドを実行することです。
show args
環境とは、 環境変数とその値の集合のことです。 環境変数は、 慣例として、 ユーザ名、 ユーザのホーム・ディレクトリ、 端末タイプ、 実行プログラムのサーチ・パスなどを記録します。 通常、 環境変数はシェル上で設定され、 ユーザの実行するすべてのプログラムによって継承されます。 デバッグ時には、 GDBを終了・再起動せずに環境を変更して、 ユーザ・プログラムを実行できると便利でしょう。
path directory
PATH
(実行ファイルのサーチ・パス)
の先頭に追加します。
これは、
GDBとユーザ・プログラムの両方に対して有効です。
`:'
(コロン)
またはスペースで区切られた複数のディレクトリを指定することもできます。
環境変数PATH
の中に既にdirectoryが含まれている場合には、
directoryは環境変数PATH
の先頭に移動されます。
これにより、
directoryはより早く検索されることになります。
文字列`$cwd'によって、
GDBがパスを検索する時点における作業ディレクトリを参照することができます。
`.'
(ピリオド)
を使用すると、
path
コマンドを実行したディレクトリを参照することになります。
directory引数に`.'
(ピリオド)
が含まれていると、
GDBはまずそれを
(カレント・ディレクトリに)
置き換えてから、
サーチ・パスに追加します。
show paths
PATH
の値)を表示します。
show environment [varname]
environment
はenv
に省略可能です。
set environment varname [=] value
set env USER = foo
unset environment varname
unset environment
は、
環境変数の値として空文字列をセットするのではなく、
環境変数そのものを環境から削除します。
注意: GDBは、
環境変数SHELL
により指定されるシェル
(環境変数SHELL
が設定されていない場合には/bin/sh
)
を使用してプログラムを実行します。
SHELL
環境変数の指定するシェルが初期化ファイルを実行するものである場合
(例えば、
C-shellの`.cshrc'、
BASHの`.bashrc')、
初期化ファイルの中で設定された環境変数はユーザ・プログラムに影響を与えます。
環境変数の設定は、
`.login'や`.profile'のように、
ユーザがシステム内に入るときに実行されるファイルに移したほうがよいでしょう。
run
コマンドで実行されるユーザ・プログラムは、
実行時のGDBの作業ディレクトリを継承します。
GDBの作業ディレクトリは、
もともと親プロセス
(通常はシェル)
から継承したものですが、
cd
コマンドによって、
GDBの中から新しい作業ディレクトリを指定することができます。
GDBの作業ディレクトリは、
GDBによって操作されるファイルを指定するコマンドに対して、
デフォルト・ディレクトリとして機能します。
ファイルを指定するコマンドを参照してください。
cd directory
pwd
GDB配下で実行されるプログラムは、 デフォルトでは、 GDBと同一の端末に対して入出力を行います。 GDBは、 ユーザとのやりとりのために、 端末モードをGDB用に変更します。 このとき、 ユーザ・プログラムが使用していた端末モードは記録され、 ユーザ・プログラムを継続実行すると、 そのモードに戻ります。
info terminal
run
コマンドにおいてシェルのリダイレクト機能を使用することによって、
ユーザ・プログラムの入出力をリダイレクトすることが可能です。
例えば、
run > outfile
はユーザ・プログラムの実行を開始し、
その出力をファイル`outfile'に書き込みます。
ユーザ・プログラムの入出力先を指定する別の方法に、
tty
コマンドがあります。
このコマンドはファイル名を引数として取り、
そのファイルを後に実行されるrun
コマンドのデフォルトの入出力先とします。
このコマンドはまた、
後のrun
コマンドにより生成される子プロセスを制御する端末を変更します。
例えば、
tty /dev/ttyb
は、
それ以降に実行されるrun
コマンドによって起動されるプロセスの
デフォルトの入出力先および制御端末を`/dev/ttyb'端末とします。
run
コマンド実行時に明示的にリダイレクト先を指定することで、
tty
コマンドで指定された入出力装置を変更することができますが、
制御端末の設定は変更できません。
tty
コマンドを使用した場合も、
run
コマンドで入力をリダイレクトした場合も、
ユーザ・プログラムの入力元だけが変更されます。
これらのコマンドを実行しても、
GDBの入力元は、ユーザの使用している端末のままです。
attach process-id
info files
コマンドで、
現在デバッグ対象となっているプログラムの情報が表示されます)。
このコマンドは、
プロセスIDを引数に取ります。
UNIXプロセスのプロセスIDを知るのに通常使用する方法は、
ps
ユーティリティ、
または、
シェル・コマンドの`jobs -l'の実行です。
attach
コマンドを実行後RETキーを押しても、
コマンドは再実行されません。
attach
コマンドを使用するには、
プロセスをサポートする環境でユーザ・プログラムを実行する必要があります。
例えば、
オペレーティング・システムの存在しないボード・コンピュータのような環境で動作するプログラムに対して、
attach
コマンドを使うことはできません。
さらに、
ユーザは、
プロセスに対してシグナルを送信する権利を持っている必要があります。
attach
コマンドを使用すると、
デバッガは、
まずカレントな作業ディレクトリの中で、
プロセスにより実行されているプログラムを見つけようとします。
(プログラムが見つからなければ)
次に、
ソース・ファイルのサーチ・パス
(ソース・ディレクトリの指定を参照)
を使用して、
プログラムを見つけようとします。
file
コマンドを使用して、
プログラムをロードすることも可能です。
ファイルを指定するコマンドを参照してください。
指定されたプロセスをデバッグする準備が整った後に、
GDBが最初にすることは、
そのプロセスを停止することです。
run
コマンドを使用してプロセスを起動した場合は、
通常使用可能なすべてのGDBコマンドを使用して、
アタッチされたプロセスの状態を調べたり変更したりすることができます。
ブレイクポイントの設定、
ステップ実行、
継続実行、
記憶域の内容の変更が可能です。
プロセスの実行を継続したいのであれば、
GDBがプロセスにアタッチした後に、
continue
コマンドを使用することができます。
detach
detach
コマンドを使用してそのプロセスをGDBの管理から解放することができます。
プロセスからディタッチしても、
そのプロセスは実行を継続します。
detach
コマンド実行後は、
ディタッチされたプロセスと
GDBは互いに完全に依存関係がなくなり、
attach
コマンドによる別のプロセスへのアタッチや、
run
コマンドによる別のプロセスの起動が可能になります。
detach
コマンドを実行後RETキーを押しても、
detach
コマンドは再実行されません。
プロセスがアタッチされている状態で、
GDBを終了したりrun
コマンドを使用したりすると、
アタッチされたプロセスを終了させてしまいます。
デフォルトの状態では、
このようなことを実行しようとすると、
GDBが確認を求めてきます。
この確認処理を行うか否かは、
set confirm
コマンドで設定可能です
(オプションの警告およびメッセージを参照)。
kill
このコマンドは、
実行中のプロセスではなく、
コア・ダンプをデバッグしたいときに便利です。
GDBは、
ユーザ・プログラムの実行中は、
コア・ダンプ・ファイルを無視します。
いくつかのオペレーティング・システム上では、
GDBの管理下でブレイクポイントを設定されている状態のプログラムを、
GDBの外で実行することができません。
このような場合、
kill
コマンドを使用することで、デバッガの外でのプログラムの実行が可能になります。
kill
コマンドは、
プログラムを再コンパイル、
再リンクしたい場合にも便利です。
というのは、
多くのシステムでは、
プロセスとして実行中の実行ファイルを更新することはできないからです。
次にrun
コマンドを実行したときに、
GDBは、
実行ファイルが変更されていることを認識し、
シンボル・テーブルを再度読み込みます
(この際、その時点でのブレイクポイントの設定を維持しようと試みます)。
いくつかのオペレーティング・システムは、
`/proc'と呼ばれる便利な機能を提供しています。
これは、
ファイル・システム関連のサブルーチンを使用して、
実行中プロセスのイメージを調べるのに使用することができます。
GDBが、
この機能を持つオペレーティング・システム用に構成されていれば、
info proc
コマンドを使用することで、
ユーザ・プログラムを実行しているプロセスに関するいくつかの情報を知ることができます。
info proc
は、
procfs
をサポートするSVR4システム上でのみ機能します。
info proc
info proc mappings
info proc times
info proc id
info proc status
info proc all
HP-UXやSolarisのようなオペレーティング・システムにおいては、 1つのプログラムが複数のスレッドを実行することができます。 「スレッド」の正確な意味は、 オペレーティング・システムによって異なります。 しかし、 一般的には、 1つのアドレス空間を共有するという点を除けば、 プログラム内のマルチスレッドは、 マルチプロセスと類似しています (アドレス空間の共有とは、 複数のスレッドが同一の変数の値を参照したり変更したりすることが可能であるということです)。 その一方で、 個々のスレッドは自分用のレジスタ、 実行スタック、 そしておそらくはプライベート・メモリを持ちます。 GDBは、 マルチスレッド・プログラムのデバッグ用に、 以下のような便利な機能を提供しています。
注意: これらの機能は、 スレッドをサポートするオペレーティング・システム用に構成された すべてのGDBで使用可能なわけではありません。 GDBがスレッドをサポートしていない環境では、 これらのコマンドは無効です。 例えば、 スレッドをサポートしていないシステム上で GDBの`info threads'コマンドを実行しても何も表示されませんし、
thread
コマンドの実行は常に拒絶されます。(gdb) info threads (gdb) thread 1 Thread ID 1 not known. Use the "info threads" command to see the IDs of currently known threads.
GDBのスレッド・デバッグ機能により、 ユーザ・プログラムの実行中に、 すべてのスレッドを観察することができます。 ただし、 GDBに制御権のある状態では、 特定の1つのスレッドだけがデバッグの対象となります。 このスレッドは、 カレント・スレッドと呼ばれます。 デバッグ用のコマンドは、 カレント・スレッドの立場から見たプログラムの情報を表示します。 ユーザ・プログラム内部において新しいスレッドの存在を検出すると、 GDBは、 `[New systag]'という形式で、 ターゲット・システム上におけるこのスレッドのIDを表示します。 ここでsystagとはスレッドのIDで、 その形式はシステムによって異なります。 例えば、 LynxOS上では、 GDBが新しいスレッドを検出すると、
[New process 35 thread 27]
のように表示されます。 一方、 SGIのシステム上では、 systagは単に`process 368'のような形式で、 これ以外の情報は含まれません。 GDBは、 ユーザ・プログラム内の個々のスレッドに対して、 デバッグ用の整数値のスレッド番号を独自に割り当てます。
info threads
(gdb) info threads 3 process 35 thread 27 0x34e5 in sigpause () 2 process 35 thread 23 0x34e5 in sigpause () * 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) at threadtest.c:68
thread threadno
(gdb) thread 2 [Switching to process 35 thread 23] 0x34e5 in sigpause ()`[New ...]'メッセージと同様、 `Switching to'の後ろに表示される情報の形式は、 そのシステムにおけるスレッドの識別方法に依存します。
thread apply [threadno] [all] args
thread apply
コマンドにより、
1つのコマンドを1つ以上のスレッドに対して実行することができます。
実行対象となるスレッドのスレッド番号を、
引数threadnoに指定します。
threadnoは、
`info threads'コマンドの出力の最初のフィールドに表示される、
GDB内部のスレッド番号です。
すべてのスレッドに対してコマンドを実行するには、
thread apply all
argsコマンドを使用してください。
GDBがユーザ・プログラムを停止させるとき、 その理由がブレイクポイントであれシグナルの受信であれ、 ブレイクポイントに到達したスレッド、 または、 シグナルを受信したスレッドが自動的に選択されます。 GDBは、 `[Switching to systag]'という形式のメッセージでそのスレッドを示し、 コンテキスト切り替えの発生に注意を促します。 複数スレッドを持つプログラムの停止時や起動時のGDBの動作の詳細については、 マルチスレッド・プログラムの停止と起動を参照してください。 また、 複数スレッドを持つプログラムの中におけるウォッチポイントについては、 ウォッチポイントの設定を参照してください。
fork
関数を使用して新たにプロセスを生成するプログラムのデバッグに関しては、
GDBは特別な機能を提供していません。
プログラムがfork
を実行するとき、
GDB
は引き続き親プロセスのデバッグを継続し、
子プロセスは妨げられることなく実行を続けます。
子プロセスが実行するコードにブレイクポイントを設定してあると、
子プロセスはSIGTRAP
シグナルを受信し、
(そのシグナルをキャッチする処理がなければ)
子プロセスは終了してしまいます。
しかし、
子プロセスをデバッグしたい場合には、
それほど困難ではない回避策があります。
fork
の呼び出し後に子プロセスが実行するソース・コードの中に、
sleep
関数の呼び出しを加えてください。
GDBに子プロセスのデバッグをさせる理由がないときに遅延が発生することのないように、
特定の環境変数が設定されているときのみ、
あるいは、
特定のファイルが存在するときのみ、
sleep
関数を呼び出すようにするとよいでしょう。
子プロセスがsleep
を呼び出している間に、
ps
ユーティリティを使用して子プロセスのプロセスIDを獲得します。
次に、
GDBに対して
(親プロセスもデバッグするのであれば、
新たにGDBを起動して、
そのGDBに対して)、
子プロセスにアタッチするよう指示してください
(既に実行中のプロセスのデバッグを参照)。
これ以降は、
通常の方法でプロセスにアタッチした場合と全く同様に、
子プロセスのデバッグが可能です。