Red Hat Training

A Red Hat training course is available for RHEL 8

3.2. GDB を使用したアプリケーションの内部状況の検証

アプリケーションが正しく機能しない理由を特定するには、実行を制御し、デバッガーで内部状態を検証します。本セクションでは、このタスクに GNU Debugger (GDB) を使用する方法を説明します。

3.2.1. GNU デバッガー (GDB)

Red Hat Enterprise Linux には GNU デバッガー (GDB) が含まれ、コマンドラインユーザーインターフェイスを使用して、プログラム内で何が起こっているかを調べることができます。

GDB 機能

1 つの GDB セッションで、以下のタイプのプログラムをデバッグできます。

  • マルチスレッドプログラムおよびフォークプログラム
  • 一度に複数のプログラム
  • TCP/IP ネットワーク接続経由で接続された gdbserver ユーティリティーを使用するリモートマシンまたはコンテナー内のプログラム

デバッグの要件

実行コードをデバッグするには、GDB では、その特定のコードのデバッグ情報が必要です。

  • ユーザーが開発したプログラムでは、コードの構築中にデバッグ情報を作成できます。
  • パッケージからインストールしたシステムプログラムの場合は、debuginfo パッケージをインストールする必要があります。

3.2.2. プロセスへの GDB の割り当て

プロセスを検証するには、GDB がプロセスに 割り当てられている 必要があります。

GDB でのプログラムの起動

プログラムがプロセスとして実行していない場合は、GDB でプログラムを起動します。

$ gdb program

program は、ファイル名またはプログラムへのパスに置き換えます。

GDB は、プログラムの実行を開始するように設定します。run コマンドでプロセスの実行を開始する前に、ブレークポイントと gdb 環境を設定できます。

実行中のプロセスに GDB を割り当て

プロセスとして実行中のプログラムに GDB を割り当てるには、以下を行います。

  1. ps コマンドで、プロセス ID (pid) を検索します。

    $ ps -C program -o pid h
     pid

    program は、ファイル名またはプログラムへのパスに置き換えます。

  2. このプロセスに GDB を割り当てます。

    $ gdb -p pid

    pid は、ps の出力にある実際のプロセス ID 番号に置き換えます。

実行中のプロセスに実行中の GDB を割り当てる

実行中のプロセスに実行中の GDB を割り当てるには、以下を行います。

  1. GDB コマンド shell を使用して ps コマンドを実行し、プログラムのプロセス ID (pid) を検索します。

    (gdb) shell ps -C program -o pid h
     pid

    program は、ファイル名またはプログラムへのパスに置き換えます。

  2. attach コマンドを使用して、GDB をプログラムに割り当てます。

    (gdb) attach pid

    pid は、ps の出力にある実際のプロセス ID の番号に置き換えます。

注記

場合によっては、GDB が適切な実行ファイルを検索できない可能性があります。file コマンドを使用して、パスを指定します。

(gdb) file path/to/program

関連情報

3.2.3. GDB を使用したプログラムコードのステップ実行

GDB デバッガーがプログラムに割り当てられたら、複数のコマンドを使用して、プログラムの実行を制御できます。

前提条件

コードをステップ実行する GDB コマンド

r (run)
プログラムの実行を開始します。引数を指定して run を実行すると、プログラムが通常起動したかのように、その引数が実行ファイルに渡されます。通常は、ブレークポイントの設定後にこのコマンドを実行します。
start
プログラムの実行を開始しますが、プログラムのメイン機能の開始時に停止します。start を引数と共に実行すると、その引数が、プログラムが通常起動したかのように実行ファイルに渡されます。
c (continue)

現在の状態からプログラムの実行を継続します。プログラムの実行は、以下のいずれかが True になるまで継続します。

  • ブレークポイントに到達した場合
  • 指定の条件を満たした場合
  • プログラムによりシグナルを受信する場合
  • エラーが発生した場合
  • プログラムが終了する場合
n (next)

現在のソースファイルでコードが次の行に到達するまで、現在の状態からプログラムの実行を続行します。プログラムの実行は、以下のいずれかが True になるまで継続します。

  • ブレークポイントに到達した場合
  • 指定の条件を満たした場合
  • プログラムによりシグナルを受信する場合
  • エラーが発生した場合
  • プログラムが終了する場合
s (step)
step コマンドは、現在のソースファイル内のコードの連続行ごとに実行を停止することも行います。ただし、関数呼び出し を含むソース行で実行が現在停止すると、GDB は、関数呼び出しを入力した後 (実行後ではなく)、実行を停止します。
until location
location オプションで指定したコードの場所に到達するまで、実行が継続されます。
fini (finish)

プログラムの実行を再開し、実行が関数から返されたときに停止します。プログラムの実行は、以下のいずれかが True になるまで継続します。

  • ブレークポイントに到達した場合
  • 指定の条件を満たした場合
  • プログラムによりシグナルを受信する場合
  • エラーが発生した場合
  • プログラムが終了する場合
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 つの関数呼び出しに関連付けられたデータを指します。

info

info コマンドは、さまざまな項目に関する情報を提供する汎用コマンドです。これは、説明する項目を指定するオプションを取ります。

  • 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 condition

    condition を、C または C++ 言語の条件に置き換えます。fileline は、上記と同様に、ファイル名および行数に置き換えます。

  • 全ブレークポイントおよびウォッチポイントの状態を 検査 する場合は、以下のコマンドを実行します。

    (gdb) info br
  • info br の出力で表示された 番号 を使用してブレークポイントを 削除 するには、以下のコマンドを実行します。

    (gdb) delete number
  • 指定の場所のブレークポイントを 削除 するには、次のコマンドを実行します。

    (gdb) clear file:line

関連情報

3.2.6. データへのアクセスや変更を停止するための GDB ウォッチポイントの使用

多くの場合、特定のデータが変更されたり、アクセスされるまでプログラムを実行させることには利点があります。次の例は、最も一般的な使用例です。

前提条件

  • GDB の理解

GDB でのウォッチポイントの使用

ウォッチポイントは、プログラムの実行を停止するように GDB に指示を出すマーカーです。ウォッチポイントはデータに関連付けられています。ウォッチポイントを配置するには、変数、複数の変数、またはメモリーアドレスを記述する式を指定する必要があります。

  • データの 変更 (書き込み) を行うために、ウォッチポイントを 配置 するには、次を使用します。

    (gdb) watch expression

    expression を、監視する内容を記述する式に置き換えます。変数の場合、 は、変数の名前と同じです。

  • データ アクセス (読み込み) のためのウォッチポイントを 配置 するには、以下を実行します。

    (gdb) rwatch expression
  • 任意の データへのアクセス (読み取りおよび書き込みの両方) のためにウォッチポイントを 配置 するには、以下を実行します。

    (gdb) awatch expression
  • 全ウォッチポイントおよびブレークポイントの状態を 検査 するには以下を実行します。

    (gdb) info br
  • ウォッチポイントを 削除 するには、以下を実行します。

    (gdb) delete num

    num オプションを、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
バックグラウンドでの実行が停止されます。

関連情報