3.2. GDB を使用したアプリケーションの内部状況の検証
アプリケーションが正しく機能しない理由を特定するには、実行を制御し、デバッガーで内部状態を検証します。このセクションでは、このタスクに GNU Debugger (GDB) を使用する方法を説明します。
3.2.1. GNU デバッガー (GDB) リンクのコピーリンクがクリップボードにコピーされました!
Red Hat Enterprise Linux には GNU デバッガー (GDB) が含まれ、コマンドラインユーザーインターフェイスを使用して、プログラム内で何が起こっているかを調べることができます。
GDB へのグラフィカルフロントエンドには、Eclipse 統合開発環境をインストールします。Eclipse の使用 を参照してください。
- GDB 機能
1 つの GDB セッションで、以下のタイプのプログラムをデバッグできます。
- マルチスレッドプログラムおよびフォークプログラム
- 一度に複数のプログラム
-
リモートマシン上のプログラムや、コンテナー内で
gdbserverユーティリティーを使用し、TCP/IP ネットワーク接続経由で接続されたプログラム
- デバッグの要件
実行コードをデバッグするには、GDB では、その特定のコードのデバッグ情報が必要です。
- ユーザーが開発したプログラムでは、コードの構築中にデバッグ情報を作成できます。
- パッケージからインストールしたシステムプログラムの場合は、debuginfo パッケージをインストールする必要があります。
3.2.2. プロセスへの GDB の割り当て リンクのコピーリンクがクリップボードにコピーされました!
プロセスを検査するには、GDB をプロセスに 接続する 必要があります。
手順
GDB を使用してプログラムを起動します。
GDB を使用してプログラムを起動します。
$ gdb programprogram は、ファイル名またはプログラムへのパスに置き換えます。
GDB は、プログラムの実行を開始するように設定します。
runコマンドでプロセスの実行を開始する前に、ブレークポイントとgdb環境をセットアップできます。- すでに実行中のプロセスに GDB を割り当てます。
psコマンドで、プロセス ID (pid) を検索します。$ ps -C program -o pid hpidprogram は、ファイル名またはプログラムへのパスに置き換えます。
このプロセスに GDB を割り当てます。
$ gdb -p pidpid は、
psの出力からの実際のプロセス ID 番号に置き換えます。
実行中のプログラムにアクティブな GDB セッションを割り当てます。
GDB コマンド
shellを使用してpsコマンドを実行し、プログラムのプロセス ID (pid) を検索します。(gdb) shell ps -C program -o pid hpidprogram は、ファイル名またはプログラムへのパスに置き換えます。
attachコマンドを使用して、GDB をプログラムに割り当てます。(gdb) attach pidpid は、
psの出力からの実際のプロセス ID の番号に置き換えます。注記場合によっては、GDB が対応する実行可能ファイルを見つけられないことがあります。
fileコマンドを使用して、パスを指定します。(gdb) file path/to/program
3.2.3. GDB を使用したプログラムコードのステップ実行 リンクのコピーリンクがクリップボードにコピーされました!
GDB デバッガーがプログラムに割り当てられたら、複数のコマンドを使用して、プログラムの実行を制御できます。これらのコマンドを使用すると、デバッグセッション中にコードをステップ実行したり、ブレークポイントを設定したり、プログラムのフローを制御したりできます。
これらの GDB コマンドを効果的に使用するには、以下の方法でデバッグ情報を入手する必要があります。* プログラムをデバッグ情報付きでコンパイルおよびビルドする * 関連する debuginfo パッケージをインストールする
GDB は、プログラムをステップ実行および制御するための一連のコマンドを備えています。
r (run): プログラムの実行を開始します。任意の引数を指定して run を実行すると、プログラムが通常起動したかのように、それらの引数が実行可能ファイルに渡されます。通常は、ブレークポイントの設定後にこのコマンドを実行します。
start: プログラムの実行を開始しますが、プログラムの main 関数の開始地点で停止します。start を任意の引数と共に実行すると、プログラムが通常起動したかのように、それらの引数が実行可能ファイルに渡されます。
c (continue): 現在の状態からプログラムの実行を継続します。プログラムの実行は、次のいずれかが満たされるまで継続されます。* ブレークポイントに到達する。* 指定された条件が満たされる。* プログラムがシグナルを受信する。* エラーが発生する。* プログラムが終了する。
n (next): 現在のソースファイル内にある次のコード行に達するまで、現在の状態からプログラムの実行を継続します。プログラムの実行は、次のいずれかが満たされるまで継続されます。* ブレークポイントに到達する。* 指定された条件が満たされる。* プログラムがシグナルを受信する。* エラーが発生する。* プログラムが終了する。
s (step): step コマンドは、現在のソースファイル内の各コード行で実行を停止します。ただし、実行が 関数呼び出し を含むソース行で停止中の場合には、GDB は、関数呼び出しを入力した後 (実行後ではなく)、実行を停止します。
until location: location オプションで指定されたコードの場所に到達するまで実行を継続します。
fini (finish): プログラムの実行を再開し、関数から抜けて戻ってきた時点で停止します。プログラムの実行は、次のいずれかが満たされるまで継続されます。* ブレークポイントに到達する。* 指定された条件が満たされる。* プログラムがシグナルを受信する。* エラーが発生する。* プログラムが終了する。
q (quit): 実行を終了し、GDB を終了します。
3.2.4. GDB でのプログラム内部値の表示 リンクのコピーリンクがクリップボードにコピーされました!
プログラムの内部変数の値を表示することは、プログラムの実行内容を理解する際に重要です。GDB は、内部変数の検査に使用できる複数のコマンドを提供します。これらのコマンドの中で最も有用なものは次のとおりです。
p(print)指定された引数の値を表示します。通常、引数は単純な 1 つの値から構造まで、あらゆる複雑な変数の名前です。引数には、プログラム変数やライブラリー関数の使用、テストするプログラムに定義する関数など、現在の言語で有効な式も指定できます。
pretty-printer Python スクリプトまたは Guile スクリプトを使用して GDB を拡張し、
printコマンドを使用して、(クラス、構造などの) データ構造をカスタマイズ表示することができます。bt(backtrace)現在の実行ポイントに到達するために使用される関数呼び出しのチェーン、または実行が終了するまで使用される関数のチェーンを表示します。これは、深刻なバグ (セグメント障害など) を調査し、見つけるのが困難な原因に役に立ちます。
backtraceコマンドにfullオプションを追加すると、ローカル変数も表示されます。btコマンドおよびinfo frameコマンドを使用して表示されるデータをカスタマイズして表示するために、frame filter Python スクリプトで GDB を拡張できます。フレーム という用語は、1 つの関数呼び出しに関連付けられたデータを指します。infoinfoコマンドは、さまざまな項目に関する情報を提供する汎用コマンドです。これは、説明する項目を指定するオプションを取ります。-
info argsコマンドは、現在選択されているフレームの関数呼び出しのオプションを表示します。 -
info localsコマンドは、現在選択されているフレームにローカル変数を表示します。
使用できる項目をリスト表示するには、GDB セッションで
help infoコマンドを実行します。(gdb) help info-
l(list)- プログラムのソースコードを表示します。プログラムが開始されていて現在停止中の場合、このコマンドは、プログラムが停止している位置のソースコードと、数行のコンテキストを表示します。プログラムが起動される前に、メイン関数がリスト表示されます。list は、厳密には内部状態を表示するコマンドではありませんが、プログラムの実行における次の手順で、内部状態にどのような変更が発生するかをユーザーが理解するのに役立ちます。
3.2.5. 定義したコードの場所で実行を停止するための GDB ブレークポイントの使用 リンクのコピーリンクがクリップボードにコピーされました!
多くの場合、コードの一部のみが検証されます。ブレークポイントは、コード内の特定の場所でプログラムの実行を停止するように GDB に指示を出すマーカーです。ブレークポイントは、ソースコードの行に関連付けられているのが最も一般的です。その場合、ブレークポイントを配置するには、ソースファイルと行番号を指定する必要があります。
手順
ブレークポイントを配置 するには、以下を実行します。
ソースコード ファイル の名前と、そのファイルの 行 を指定します。
(gdb) br file:lineファイル が存在しない場合は、現在の実行ポイントにソースファイルの名前が使用されます。
(gdb) br lineまたは、関数名を使用して、起動時にブレークポイントを配置します。
(gdb) br function_nameタスクを特定の回数反復すると、プログラムでエラーが発生する可能性があります。実行を停止するために追加の 条件 を指定するには、以下を実行します。
(gdb) br file:line if conditioncondition を、C または C++ 言語の条件に置き換えます。file と line は、上記と同様に、ファイル名および行数に置き換えます。
全ブレークポイントおよびウォッチポイントの状態を 検査 する場合は、以下のコマンドを実行します。
(gdb) info brinfo brの出力で表示された 番号 を使用してブレークポイントを 削除 するには、以下のコマンドを実行します。(gdb) delete number指定の場所のブレークポイントを 削除 するには、次のコマンドを実行します。
(gdb) clear file:line
3.2.6. データへのアクセスや変更を停止するための GDB ウォッチポイントの使用 リンクのコピーリンクがクリップボードにコピーされました!
多くの場合、特定のデータが変更されたり、アクセスされるまでプログラムを実行させることには利点があります。ウォッチポイントは、特定のデータ条件が満たされたときにプログラムの実行を停止するように GDB に指示するマーカーです。
手順
データ変更 (書き込み) のウォッチポイントを配置するには、以下を実行します。
(gdb) watch expressionexpression を、監視する内容を記述する式に置き換えます。変数の場合、式 は、変数の名前と同じです。
データアクセス (読み取り) のウォッチポイントを配置するには、以下を実行します。
(gdb) rwatch expressionすべてのデータアクセス (読み取りと書き込みの両方) にウォッチポイントを配置するには、以下を実行します。
(gdb) awatch expressionすべてのウォッチポイントとブレークポイントのステータスを検査するには、以下を実行します。
(gdb) info brウォッチポイントを削除するには、以下を実行します。
(gdb) delete numnum オプションは、
info brコマンドで報告される数値に置き換えます。
3.2.7. GDB でのフォークまたはスレッド化されたプログラムのデバッグ リンクのコピーリンクがクリップボードにコピーされました!
プログラムによっては、フォークまたはスレッドを使用して、並行コード実行を実現します。複数の同時実行パスをデバッグするには、特別な留意点があります。
プロセスのフォークおよびスレッドの概念を理解している。
- GDB でのフォークされたプログラムのデバッグ
フォークとは、プログラム (親) が独立したコピー (子) を作成する状況です。フォーク発生時の GDB の動作に影響を与えるには、以下の設定およびコマンドを使用します。
follow-fork-mode設定で、フォークの後に GDB が親または子に従うかどうかを制御します。set follow-fork-mode parent- フォークの後に、親プロセスのデバッグを実行します。これがデフォルトになります。
set follow-fork-mode child- フォークの後に子のプロセスをデバッグします。
show follow-fork-mode-
follow-fork-modeの現在の設定を表示します。
set detach-on-fork設定では、GDB が (フォローしていない) 他のプロセスを制御するか、そのまま実行させるかを制御します。set detach-on-fork on-
フォローされないプロセス (
follow-fork-modeの値によって異なる) は切り離され、独立して実行されます。これがデフォルトになります。 set detach-on-fork off-
GDB は両方のプロセスの制御を維持します。フォローされるプロセス (
follow-fork-modeの値によって異なる) は通常どおりデバッグされ、他のプロセスは中断されます。 show detach-on-fork-
detach-on-forkの現在の設定を表示します。
- GDB でのスレッド化されたプログラムのデバッグ
-
GDB には、個別のスレッドをデバッグして、独立して操作し、検査する機能があります。GDB が検査したスレッドのみを停止するようにするには、
set non-stop onコマンドおよびset target-async onコマンドを使用します。これらのコマンドは、.gdbinitファイルに追加できます。その機能が有効になると、GDB がスレッドのデバッグを実行する準備が整います。
GDB は、現在のスレッド の概念を使用します。デフォルトでは、コマンドは現在のスレッドのみに適用されます。
info threads-
現在のスレッドを示す
id番号およびgid番号を使用してスレッドのリストを表示します。 thread id-
指定した
idを現在のスレッドとして設定します。 thread apply ids command-
commandコマンドを、idsでリスト表示されたすべてのスレッドに適用します。idsオプションは、スペースで区切られたスレッド ID のリストです。特殊な値allは、すべてのスレッドにコマンドを適用します。 break location thread id if condition-
スレッド番号
idに対してのみ特定のconditionを持つ特定のlocationにブレークポイントを設定します。 watch expression thread id-
スレッド番号
idに対してのみexpressionで定義されるウォッチポイントを設定します。 command&-
commandコマンドを実行して、すぐに gdb プロンプト(gdb)に戻りますが、バックグラウンドでコード実行が続行されます。 interrupt- バックグラウンドでの実行が停止されます。