20.2. GDB を使用したアプリケーションの内部状態の検査

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

20.2.1. GNU デバッガー (GDB)

デバッガーは、コード実行の制御や、コードの状態の検査を有効にするツールです。この機能は、プログラム内で何が発生しているのか、またその発生理由についての調査に使用します。

Red Hat Enterprise Linux には、コマンドラインユーザーインターフェースでこの機能を提供する GNU デバッガー (GDB) が含まれます。

GDB へのグラフィカルフロントエンドについては、Eclipse 統合開発環境をインストールします。「Using Eclipse」を参照してください。

GDB 機能

単一の GDB セッションで、以下をデバッグできます。

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

実行可能なコードをデバッグするには、GDB では適切なデバッグ情報が必要です。

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

20.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
関連資料

20.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 を終了します。
関連資料

20.2.4. GDB でのプログラム内部値の表示

プログラムの内部変数の値を表示することは、プログラムの実行内容を理解する際に重要です。GDB は、内部変数の検査に使用できる複数のコマンドを提供します。このセクションでは、これらのコマンドの中で最も有用なものを説明します。

前提条件
  • 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 は、厳密には内部状態を表示するコマンドではありませんが、ユーザーがプログラムの実行の次の手順で内部状態にどのような変更が発生するかを理解するのに役立ちます。
関連資料

20.2.5. 定義したコードの場所で実行を停止するための GDB ブレークポイントの使用

多くの場合、特定のコードの行に到達するまでプログラムを実行させることには利点があります。

前提条件
  • GDB を理解していること
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
関連資料

20.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 コマンドで報告される番号に置き換えます。

関連資料

20.2.7. GDB でのフォーク用またはスレッド化されたプログラムのデバッグ

プログラムによっては、フォークまたはスレッドを使用して、コードの並行実行を実行します。複数の同時実行パスをデバッグするには、特別な留意点があります。

前提条件
  • 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 は current thread の概念を使用します。デフォルトでは、コマンドは現在のスレッドのみに適用されます。

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
バックグラウンドでの実行が停止されます。
関連資料

このページには機械翻訳が使用されている場合があります (詳細はこちら)。