第20章 実行中のアプリケーションのデバッグ
本章では、開発者が直接アクセスできるマシンで、必要に応じて何度でも起動でき、アプリケーションをデバッグする方法を紹介します。
20.1. デバッグ情報を使用したデバッグの有効化
アプリケーションやライブラリーをデバッグするには、デバッグ情報が必要です。以下のセクションでは、この情報を取得する方法を説明します。
20.1.1. デバッグの情報
実行可能なコードをデバッグする場合に、ツールやプログラマーは 2 種類の情報を使用して、バイナリーコードを理解することができます。
- ソースコードテキスト
- ソースコードテキストがバイナリーコードにどのように関連しているのかの説明
上記がデバッグ情報と呼ばれるものです。
Red Hat Enterprise Linux は、実行可能なバイナリー、共有ライブラリー、または debuginfo ファイルに ELF 形式を使用します。この ELF ファイルでは、DWARF 形式を使用してデバッグ情報を保持します。
DWARF シンボルは、readelf -w file コマンドを使用して読み込みます。
STABS は UNIX で使用される場合もあります。STABS は、機能が少ない旧式の形式です。Red Hat は、STABS の使用は推奨していません。GCC および GDB は、STABS の実稼働および使用はベストエフォートでのみサポートされます。Valgrind および elfutils などの他のツールでは、STABS のサポートはありません。
その他のリソース
20.1.2. GCC を使用した C および C++ アプリケーションのデバッグの有効化
デバッグの情報が大きい場合には、デフォルトでは実行可能ファイルは含まれません。GCC を使用した C および C++ アプリケーションのデバッグを有効化するには、コンパイラーに対して、ファイルを作成するように、明示的に指示する必要があります。
GCC を使用したデバッグ情報の作成の有効化
コードのコンパイルおよびリンク時には GCC でデバッグ情報の作成を有効化するには、-g オプションを使用します。
$ gcc ... -g ...
-
コンパイラーとリンカーで最適化を行うと、実行可能なコードを、元のソースコードと関連付けることが難しくなります。変数の最適化、ループのアンロール、周りの操作へのマージなどが行われる可能性があります。デバッグの体験を向上するには、
-Ogオプションを指定して、最適化を設定することを考慮してください。ただし、最適化レベルを変更すると、実行可能なコードが変更され、バグを取り除くための実際の動作が変更される可能性があります。 -
-fcompare-debugGCC オプションでは、GCC でコンパイルしたコードを、デバッグ情報を使用して (または、デバッグ情報を使用せずに) テストします。このテストでは、出力されたバイナリーファイル 2 つが同一であれば合格します。このテストを行うことで、実行可能なコードはデバッグオプションによる影響は受けないようにするだけでなく、デバッグコードにバグが含まれないようにします。-fcompare-debugオプションを使用するとコンピレーションの時間が大幅に伸びます。このオプションに関する詳細情報は、GCC の man ページを参照してください。
その他のリソース
- 「デバッグ情報を使用したデバッグの有効化」
- GNU コンパイラーコレクション (GCC) の使用: 「Options for Debugging Your Program」
- GDB でのデバッグ: 「Debugging Information in Separate Files」
GCC の man ページ:
$ man gcc
20.1.3. Debuginfo パッケージ
Debuginfo パッケージには、プログラムとライブラリーのデバッグ情報と、デバッグソースコードが含まれます。
前提条件/事前作業
Debuginfo パッケージ
Red Hat Enterprise Linux リポジトリーのパッケージにインストールされているアプリケーションやライブラリーの場合は、別のチャンネルで提供されている別の debuginfo パッケージにとしてデバッグ情報とデバッグソースコードを取得することができます。debuginfo パッケージには .debug ファイルが含まれており、その中には、バイナリーパッケージのコンパイルに使用する DWARF debuginfo とソースファイルがあります。Debuginfo パッケージのコンテンツは、/usr/lib/debug ディレクトリーにインストールされます。
debuginfo パッケージでは、名前、バージョン、リリース、アーキテクチャーが同じバイナリーパッケージでのみ有効なデバッグ情報が提供されます。
-
バイナリーパッケージ:
packagename-version-release.architecture.rpm -
Debuginfo パッケージ:
packagename-debuginfo-version-release.architecture.rpm
20.1.4. GDB を使用したアプリケーションまたはライブラリー向けの debuginfo パッケージ取得
GNU デバッガー (GDB) は、自動的に足りないデバッグ情報を認識して、パッケージ名を解決します。
前提条件/事前作業
- デバッグするアプリケーションまたはライブラリーがシステムにインストールされていること
- システムに GDB がインストールされていること
-
システムに
debuginfo-installツールがインストールされていること
手順
デバッグするアプリケーションまたはライブラリーにアタッチされている GDB を起動します。GDB は自動的に、足りないデバッグ情報を認識して、実行するコマンドを提案します。
$ gdb -q /bin/ls Reading symbols from /usr/bin/ls...Reading symbols from /usr/bin/ls...(no debugging symbols found)...done. (no debugging symbols found)...done. Missing separate debuginfos, use: debuginfo-install coreutils-8.22-21.el7.x86_64 (gdb)これ以上何もせずに、GDB を終了します。q を入力して、Enter を押します。
(gdb) q
GDB が提案するコマンドを実行して、必要な debuginfo パッケージをインストールします。
# debuginfo-install coreutils-8.22-21.el7.x86_64
アプリケーションまたはライブラリーの debuginfo パッケージをインストールすると、依存関係の debuginfo パッケージもすべてインストールされます。
- GDB が debuginfo パッケージを提案できない場合には、「手動でのアプリケーションまたはライブラリー向けの debuginfo パッケージ取得」の手順に従ってください。
その他のリソース
20.1.5. 手動でのアプリケーションまたはライブラリー向けの debuginfo パッケージ取得
実行可能ファイルの場所を特定して、そのファイルをインストールするパッケージを検索し、インストール用の debuginfo パッケージを手動で判断できます。
GDB を使用してインストールするパッケージを決定すること を推奨します。GDB によりインストールするパッケージが提案されない場合にのみ、この手動の手順を使用してください。
前提条件/事前作業
- アプリケーションまたはライブラリーをシステムにインストールしておくこと
- debuginfo-install ツールをシステムで利用できるようにしておくこと
手順
アプリケーションまたはライブラリーの実行可能ファイルを検索します。
whichコマンドを使用して、アプリケーションファイルを検索します。$ which nautilus /usr/bin/nautiluslocateコマンドを使用して、ライブラリーファイルを検索します。$ locate libz | grep so /usr/lib64/libz.so /usr/lib64/libz.so.1 /usr/lib64/libz.so.1.2.7デバッグの理由がエラーメッセージに含まれていた場合には、ライブラリーのファイル名に同じ追加の数字が含まれる結果を選択します。分からない場合は、ライブラリーのファイル名に追加の数字が含まれていない結果を使用して、残りの手順を実行してください。
注記locateコマンドは mlocate パッケージで提供されます。このパッケージをインストールして使用を有効にするには以下を実行します。# yum install mlocate # updatedb
ファイルパスを使用して、対象のファイルを提供するパッケージを検索します。
# yum provides /usr/lib64/libz.so.1.2.7 Loaded plugins: product-id, search-disabled-repos, subscription-manager zlib-1.2.7-17.el7.x86_64 : The compression and decompression library Repo : @anaconda/7.4 Matched from: Filename : /usr/lib64/libz.so.1.2.7この出力では、
name-version.distribution.platformの形式でパッケージ一覧が表示されます。yumの出力で表示されるバージョンは実際にインストールされているバージョンでない場合があるので、この手順では、パッケージの 名前 のみが重要です。重要この手順では結果が返されないので、どのパッケージがバイナリーファイル用のパッケージであるか、この手順が失敗したかの判断ができません。
rpmの低レベルのパッケージ管理ツールを使用して、どのパッケージバージョンがシステムにインストールされているのかを確認します。パッケージ名を引数として使用します。$ rpm -q zlib zlib-1.2.7-17.el7.x86_64この出力では、
name-versiondistribution.platformの形式でインストールされたパッケージの詳細が表示されます。debuginfo-installユーティリティーを使用して debuginfo パッケージをインストールします。このコマンドでは、前の手順で判断したパッケージ名などの情報を使用します。# debuginfo-install zlib-1.2.7-17.el7.x86_64アプリケーションまたはライブラリーの debuginfo パッケージをインストールすると、依存関係の debuginfo パッケージもすべてインストールされます。
その他のリソース
- 『Red Hat Developer Toolset User Guide』: 「1.5.4. Installing Debugging Information」
- 「How can I download or install debuginfo packages for RHEL systems?」: ナレッジベースのアーティクル
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 programprogram は、ファイル名またはプログラムへのパスに置き換えます。
GDB は、プログラムの実行を開始するように設定します。ブレークポイントと gdb 環境を設定してから、run コマンドでプロセスの実行を開始するようにしてください。
すでに実行中のプロセスへの GDB のアタッチ
プロセスとしてすでに実行中のプログラムに GDB をアタッチするには、以下を実行します。
psコマンドで、プロセス id (pid) を検索します。$ ps -C program -o pid h pid
program は、ファイル名またはプログラムへのパスに置き換えます。
このプロセスに GDB をアタッチします。
$ gdb -p pidpid は、
psの出力にある実際のプロセス id の数字に置き換えます。
すでに実行中のプロセスに実行中の GDB をアタッチする手順
すでに実行中のプロセスに実行中の GDB をアタッチします。
shellGDB コマンドを使用して、psコマンドを実行し、プログラムのプロセス id (pid) を特定します。(gdb) shell ps -C program -o pid h pid
program は、ファイル名またはプログラムへのパスに置き換えます。
attachコマンドを使用して、GDB をプログラムにアタッチします。(gdb) attach pidpid は、
psの出力にある実際のプロセス id の数字に置き換えます。
場合によっては GDB は適切な実行可能ファイルを検索できない可能性があります。file コマンドを使用して、パスを指定してください。
(gdb) file path/to/programその他のリソース
- GDB でのデバッグ: 「2.1 Invoking GDB」
- GDB でのデバッグ: 「4.7 Debugging an Already-running Process」
20.2.3. GDB でのプログラムコードの活用
GDB デバッガーがプログラムにアタッチされたら、複数のコマンドを使用して、プログラムの実行を制御できます。
前提条件/事前作業
- 「GDB をシステムにインストールしておくこと」
必要なデバッグ情報を利用できる状態にしておくこと
- プログラムはコンパイルされ、デバッグ情報で構築されていること、または
- 適切な debuginfo パッケージがインストールされていること
- GDB がデバッグするプログラムにアタッチされていること
コードを活用するための GDB コマンド
r(run)-
プログラムの実行を開始します。引数を指定して
runを実行すると、プログラムが通常通り開始されたかのように、その引数が実行可能ファイルに渡されます。ユーザーは通常、ブレークポイントを設定してから、このコマンドを実行します。 start-
プログラムの実行を開始し、プログラムの主な機能の開始時点で停止します。引数を指定して
startを実行すると、これらの引数は、プログラムが通常に起動したかのように、実行可能ファイルに渡されます。
c(continue)現在の状態からプログラムの実行を継続します。プログラムの実行は、以下のいずれかが真になるまで継続されます。
- ブレークポイントに到達した場合
- 指定の条件を満たした場合
- プログラムからシグナルを受け取った場合
- エラーが発生した場合
- プログラムが終了された場合
n(next)現在のソースファイルでコードが次の行に移動するまで、現在の状態からプログラムの実行を続けます。プログラムの実行は、以下の内容が真になるまで継続されます。
- ブレークポイントに到達した場合
- 指定の条件を満たした場合
- プログラムからシグナルを受け取った場合
- エラーが発生した場合
- プログラムが終了された場合
s(step)-
stepコマンドは、現在のソースファイルのコード行ごとに実行を停止させます。ただし、実行が 関数呼び出し が含まれるソースの行で停止中の場合には、GDB は (関数呼び出しを実行するのではなく)、関数呼び出しに入る前に実行を停止します。 untillocation- location で指定したコードの場所に到達するまで、実行が継続されます。
fini(finish)プログラムの実行を再開し、実行が関数から戻り値として返された時点で停止します。プログラムの実行は、以下のいずれかが真になるまで継続されます。
- ブレークポイントに到達した場合
- 指定の条件を満たした場合
- プログラムからシグナルを受け取った場合
- エラーが発生した場合
- プログラムが終了された場合
q(quit)- 実行を中断して、GDB を終了します。
その他のリソース
- 「定義したコードの場所で実行を停止するための GDB ブレークポイントの使用」
- GDB でのデバッグ: 「4.2 Starting your Program」
- GDB でのデバッグ: 「5.2 Continuing and Stepping」
20.2.4. GDB でのプログラム内部値の表示
プログラムの内部変数の値を表示することは、プログラムが何を実行しているかを理解する場合に重要です。GDB には、内部変数の検証に使用可能なコマンドが複数含まれています。このセクションでは、これらのコマンドの中で最も有用なものを説明します。
前提条件/事前作業
- GDB デバッガーを理解していること
プログラムの内部の状態を表示するための GDB コマンド
p(print)指定した引数の値を表示します。引数には通常、単純な値 1 つや構造など、あらゆる複雑性の変数名を指定できます。引数には、プログラム変数やライブラリー関数での用途、テストするプログラムに定義する関数など、現在の言語で有効な表現も指定できます。
pretty-printer Python または Guile スクリプトを使用して GDB を拡張し、
printコマンドを使用して、(クラス、構造など) データ構造をカスタマイズ表示することができます。bt(backtrace)現在の実行ポイントに到達するために使用する関数呼び出しチェーンや、実行が中断されるまで使用する関数チェーンを表示します。これは、原因を特定しにくい、深刻なバグ (セグメント障害など) を調査する場合に便利です。
backtraceコマンドにfullオプションを追加すると、ローカルの変数も表示されます。frame filter Python スクリプトを使用して GDB を拡張し、
btとinfo frameコマンドでデータをカスタマイズして表示することができます。frame は、単一の関数呼び出しに関連付けられたデータを参照します。infoinfoコマンドは、様々な項目に関する情報を表示するための汎用コマンドです。このコマンドでは、説明を確認する項目をオプションとして指定できます。-
info argsコマンドは、現在選択されているフレームの関数呼び出しオプションを表示します。 -
info localsコマンドは、現在選択されているフレームにローカルの変数を表示します。
指定可能なオプションを一覧表示するには、GDB セッションで
help infoのコマンドを実行します。(gdb) help info
-
l(list)-
プログラムが停止したソースコードの行を表示します。このコマンドは、プログラムの実行が停止された場合のみ利用できます。
listは、内部の状態を厳密に表示するコマンドではありませんが、プログラム実行の次のステップでどのような変更が内部状態に加えられるのかを理解することができます。
その他のリソース
- 「The GDB Python API」: Red Hat 開発者のブログ投稿
- GDB でのデバッグ: 「10.9 Pretty Printing」
20.2.5. 定義したコードの場所で実行を停止するための GDB ブレークポイントの使用
多くの場合、特定のコードの行に到達するまでプログラムを実行させると有益です。
前提条件/事前作業
- GDB を理解していること
GDB でのブレークポイントの使用
ブレークポイントは、プログラムの実行を停止するように GDB に指示を出すためのマーカーです。ブレークポイントは一般的に、ソースコードの行と関連付けられており、ブレークポイントを配置するには、ソースファイルと行数を指定する必要があります。
ブレークポイントを配置する方法:
ソースコードの ファイル 名と、そのファイルの 行 を指定します。
(gdb) br file:linefile がない場合には、現在実行中のポイントのソースファイル名を使用します。
(gdb) br lineまたは、関数名を使用して、起動時にブレークポイントを配置します。
(gdb) br function_name
タスクを特定の回数反復すると、プログラムにエラーが発生する可能性があります。実行を停止するには、追加の 条件 を指定します。
(gdb) br file:line if condition
condition は、C または C++ 言語の条件に置き換えます。file と line は、上記と同様に、ファイル名および行数に置き換えます。
全ブレークポイントおよびウォッチポイントの状態を 検証 するには以下を実行します。
(gdb) info br
info brの出力で表示された 数字 を使用して、ブレークポイントを 削除するには 以下を実行します。(gdb) delete number指定の場所のブレークポイントを 削除 するには以下を実行します。
(gdb) clear file:line
その他のリソース
- GDB でのデバッグ: 「5.1 Breakpoints, Watchpoints, and Catchpoints」
20.2.6. データへのアクセスや変更が合った場合に実行を停止するための GDB ウォッチポイントの使用
多くの場合、特定のデータが変更されるまで、または特定のデータにアクセスがあるまで、プログラムを実行させるようにすると有益です。このセクションでは、一般的なコマンドについて説明します。
前提条件/事前作業
- GDB の理解
GDB でのウォッチポイントの章
ウォッチポイントは、プログラム実行を停止するように GDB に指示を出すマーカーです。ウォッチポイントは、データと関連付けられており、ウォッチポイントを配置するには、変数を記述する表現、複数の変数、またはメモリーアドレスを指定する必要があります。
データを 変更 (書き込み) するために、ウォッチポイントを 配置 します。
(gdb) watch expressionexpression は、ウォッチの対象を記述する表現に置き換えます。変数の場合は、expression は変数名と同じです。
データに アクセス (読み取り) するために、ウォッチポイントを 配置 します。
(gdb) rwatch expressionあらゆる データにアクセス (読み取りおよび書き込み) するために、ウォッチポイントを 配置 します。
(gdb) awatch expression全ウォッチポイントおよびブレークポイントの状態を 検証 するには以下を実行します。
(gdb) info br
ウォッチポイントを 削除 するには以下を実行します。
(gdb) delete numnum オプションは、
info brコマンドで報告された数字に置き換えます。
その他のリソース
- GDB でのデバッグ: 「5.1.2 Setting Watchpoints」
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- バックグラウンドでの実行が停止されます。
その他のリソース
- GDB でのデバッグ: 「4.10 Debugging Programs with Multiple Threads」
- GDB でのデバッグ: 「4.11 Debugging Forks」
20.3. アプリケーションの対話の記録
アプリケーションの実行可能コードは、オペレーティングシステムや共有ライブラリーのコードと対話します。これらの対話に関するアクティビティーログを記録すると、実際のアプリケーションコードをデバッグせずに、アプリケーションの動作を詳細にわたり知ることができます。また、アプリケーションの対話を分析すると、バグが発生した状況をピンポイントで特定しやすくなります。
20.3.1. アプリケーションの対話の記録に役立つツール
Red Hat Enterprise Linux には、アプリケーションの対話を分析するための複数のツールが含まれます。
- strace
straceツールは主に、アプリケーションが使用するシステム呼び出し (カーネルの関数) のログ記録を有効化します。-
straceは、パラメーターを解釈し、下層のカーネルコードのナレッジを結果として提供するので、strace出力は詳細にわたり、呼び出しに関する詳しい情報を提供します。数字は、適切な定数名に変換され、ビット単位で統合されたフラグはフラグ一覧に拡張され、文字配列に対するポインターは実際の文字列を提供するために逆参照されます。最新のカーネル機能のサポートに欠ける場合があります。 - トレースされた呼び出しをフィルタリングして、取得するデータ量を減らすことができます。
- [command]`strace を使用するために、ログフィルターの設定以外に、特別な設定は必要ありません。
-
strace でアプリケーションコードをトレースすると、アプリケーションの実行速度が大幅に遅くなるので、多くの場合、
[command]`straceは、実稼働デプロイメントに適していません。代わりに、ltraceまたはシステムトラップの使用を検討してください。 -
Red Hat Developer Toolset で利用可能な
straceのバージョンでは、システム呼び出しで異なる結果を出すことができるので、この機能は、デバッグに役立ちます。
-
- ltrace
[command]`ltrace ツールは、アプリケーションの共有オブジェクト (動的ライブラリー) へのユーザー空間呼び出しをロギングできるようにします。
-
ltraceは、ライブラリーへの呼び出しをトレースできるようにします。 - トレースされた呼び出しをフィルタリングして、取得するデータ量を減らすことができます。
-
ltraceを使用するために、ログフィルターの設定以外に、特別な設定は必要ありません。 -
ltraceは、軽量、高速で、straceの代わりとして使用できます。straceでカーネルの関数をトレースする代わりに、ltraceでglibcなど、ライブラリー内の適切なインターフェースをトレースできます。 -
ltraceはstraceなどの既知の呼び出しを処理しないので、ライブラリーの関数に渡す値の情報は提供されません。ltraceの出力には、未処理の数字やポインターだけが含まれます。ltrace出力を解釈するには、出力に含まれるライブラリーの実際のインターフェースの宣言を確認する必要があります。
-
- SystemTap
SystemTap は、Linux システム上で実行中のプロセスおよびカーネルアクティビティをプローブするための有用なインストルメンテーションプラットフォームです。SystemTap は、独自のスクリプト言語を使用してカスタムのイベントハンドラーをプログラミングします。
-
straceやltraceの使用と比較して、ロギングをスクリプト化すると、初期の設定フェーズでの作業量が増加しますが、スクリプト機能があると、SystemTap は、ログの生成以外の利便性が増します。 - SystemTap は、カーネルモジュールを作成、挿入することで機能します。SystemTap は効率的で、システムやアプリケーションの実行速度を大幅に下げることはありません。
- SystemTap には使用例が複数含まれています。
-
- GDB
GNU デバッガーは主に、ロギングではなく、デバッグを行いますが、GNU デバッガーの機能の中で、アプリケーションの対話が主なアクティビティーとなるシナリオでも、有用なものがあります。
- GDB では、対話イベントを取得して、後に続く実行パスを即時にデバッグするように、都合よく組み合わせることができます。
- GDB は、他のツールで問題の状況を最初に特定してから、頻度の低いイベントや単一のイベントを分析するのが一番適しています。イベントの発生頻度が高い場合には、GDB の使用が非効率であったり、使用ができなくなったりします。
その他のリソース
20.3.2. strace でのアプリケーションのシステム呼び出し監視
strace ツールでは、アプリケーションを実行するシステム (カーネル) 呼び出しの監視を有効化します。
前提条件/事前作業
手順
- 監視するシステム呼び出しを特定します。
監視するプログラムが実行されていない場合は、
straceを起動して、プログラム を指定します。$ strace -fvttTyy -s 256 -e trace=call program
call は、表示されるシステム呼び出しに置き換えます。
-e trace=callオプションは複数回使用できます。何も指定しない場合は、straceは全システム呼び出しの種類を表示します。詳しい情報は strace(1) の man ページを参照してください。プログラムがすでに実行中の場合には、プロセス id (pid) を検索して、その id に
straceをアタッチします。$ ps -C program (...) $ strace -fvttTyy -s 256 -e trace=call -ppid
フォークしたプロセスまたはスレッドをトレースしない場合には、
-fオプションは指定しないでください。straceは、アプリケーションで作成したシステム呼び出しとその詳細を表示します。多くの場合、アプリケーションとそのライブラリーは大量の呼び出しを作成し、これらのシステム呼び出しにフィルターが設定されていない場合には、
straceの出力が直後に表示されます。straceは、プログラムが終了すると、終了します。トレースしたプログラムが終了する前にモニタリングを中断するには、 を押してください。
-
straceでプログラムを起動した場合には、プログラムはstraceとともに中断されます。 -
実行中のプログラムに
straceをアタッチした場合には、プログラムはstraceとともに中断されます。
-
アプリケーションが実行したシステム呼び出しの一覧を分析します。
- リソースのアクセスや可用性の問題は、エラーを返した呼び出しとしてログに表示されます。
- システム呼び出しや呼び出しシーケンスのパターンに渡す値により、アプリケーションの動作の原因が分かります。
- アプリケーションがクラッシュした場合に、重要な情報はおそらく、ログの最後に表示されます。
- 出力には、不必要な情報が多く含まれていますが、より正確なフィルターを構築して、繰り返し手順を実行してください。
出力を確認することも、ファイルに保存することもどちらも有用です。これには、tee コマンドを使用します。
$ strace ... | tee your_log_file.logその他のリソース
- strace(1) man ページ
- 「How do I use strace to trace system calls made by a command?」: ナレッジベースアーティクル
- 『Red Hat Developer Toolset User Guide』: 「Chapter 8. strace」
20.3.3. ltrace でのアプリケーションのライブラリー関数呼び出しの監視
ltrace ツールは、ライブラリー (共有オブジェクト) で利用可能な関数に対するアプリケーションの呼び出しを監視できます。
前提条件/事前作業
手順
- 可能であれば、対象のライブラリーおよび関数を特定します。
監視するプログラムが実行されていない場合には、
ltraceを起動して、プログラム を指定します。$ ltrace -f -l library -e function program
-eおよび-lのオプションを使用して、出力をフィルタリングします。-
function として表示する関数名を提示します。
-e functionオプションは複数回使用できます。何も指定しない場合は、ltraceは全関数への呼び出しを表示します。 -
関数を指定するのではなく、
-l libraryオプションでライブラリー全体を指定することができます。このオプションは、-e functionオプションと同様に動作します。
詳細情報は、ltrace(1)_ man ページを参照してください。
プログラムがすでに実行中の場合は、プロセス id (pid) を検索して、その id を指定して
ltraceを実行します。$ ps -C program (...) $ ltrace ... -ppid
フォークしたプロセスまたはスレッドをトレースしない場合には、
-fオプションは指定しないでください。-
function として表示する関数名を提示します。
ltraceはアプリケーションのライブラリー呼び出しを表示します。多くの場合、アプリケーションは大量の呼び出しを作成し、フィルターが設定されていない場合には、
ltraceの出力がすぐに表示されます。ltraceは、プログラムが終了すると、終了します。トレースしたプログラムが終了する前にモニタリングを中断するには、 を押してください。
-
ltraceでプログラムを起動した場合には、プログラムはltraceとともに中断されます。 -
ltraceをすでに実行中のプログラムにアタッチした場合には、プログラムはltraceとともに中断されます。
-
アプリケーションが実行したライブラリー呼び出しの一覧を分析します。
- アプリケーションがクラッシュした場合に、重要な情報はおそらく、ログの最後に表示されます。
- 出力には、不必要な情報が多く含まれていますが、より正確なフィルターを構築して、繰り返し手順を実行してください。
出力を確認することも、ファイルに保存することもどちらも有用です。これには、tee コマンドを使用します。
$ ltrace ... | tee your_log_file.logその他のリソース
- strace(1) man ページ
- 『Red Hat Developer Toolset User Guide 』: 「Chapter 9. ltrace」
20.3.4. SystemTap でのアプリケーションのシステム呼び出し監視
SystemTap ツールでは、カーネルイベントにカスタムイベントハンドラーを登録できるようになります。strace と比較すると、使いにくいですが、効率性が高く、より複雑な処理ロジックを使用できます。
前提条件/事前作業
手順
以下の内容を含む
my_script.stpファイルを作成します。probe begin { printf("waiting for syscalls of process %d \n", target()) } probe syscall.* { if (pid() == target()) printf("%s(%s)\n", name, argstr) } probe process.end { if (pid() == target()) exit() }監視するプロセスのプロセス ID (pid) を検索します。
$ ps -aux
スクリプトで SystemTap を実行します。
# stap my_script.stp -x pid
pid には、プロセス id を指定します。
スクリプトはカーネルモジュールにコンパイルされてから読み込まれるため、コマンドを入力してから出力が表示されるまで若干の遅延があります。
- プロセスでシステム呼び出しが実行されると、呼び出し名とパラメーターがターミナルに出力されます。
-
プロセスが中断された場合や、
Ctrl+Cが押された場合に、スクリプトは終了します。
その他のリソース
- 『SystemTap ビギナーズガイド』
- SystemTap タップセットリファレンス
-
strace機能に似た SystemTap スクリプトは/usr/share/systemtap/examples/process/strace.stpにあります。
20.3.5. GDB を使用したアプリケーションシステム呼び出しの遮断
GDB は、プログラムの実行中に発生するさまざまな状況において実行を指定できます。プログラムがシステム呼び出しを実行時に実行を停止するには、GDB catchpoint を使用します。
前提条件/事前作業
GDB でのシステム呼び出しでプログラム実行の停止
キャッチポイントを設定します。
(gdb) catch syscall syscall-namecatch syscallコマンドは、プログラムによりシステム呼び出しが行われた時に実行を停止する特別なブレークポイントを設定します。syscall-nameオプショは、呼び出し名を指定します。様々なシステム呼び出しに対して複数のキャッチポイントを指定することができます。syscall-nameオプションに何も指定しない場合には、システム呼び出しがあると、GDB が停止してしまいます。プログラムにより、実行が開始されていない場合には、開始してください。
(gdb) r
プログラムの実行が一時停止されているだけの場合は、再開してください。
(gdb) c
- GDB は、指定のシステム呼び出しがプログラムにより実行された後に実行を一時停止します。
その他のリソース
20.3.6. アプリケーションによるシグナルの処理を遮断するための GDB の使用
GDB は、プログラムの実行中に発生するさまざまな状況において実行を指定できます。プログラムがオペレーティングシステムからシグナルを受信した時に実行を停止するには、GDB catchpoint を使用します。
前提条件/事前作業
GDB でのシグナル受信時のプログラム実行停止
キャッチポイントを設定します。
(gdb) catch signal signal-typecatch signalコマンドは、プログラムでシグナルを受信した場合に、実行を一時停止する特別なブレークポイントを設定します。signal-typeオプションは、シグナルのタイプを指定します。すべてのシグナルを取得するには、特別な値'all'を使用します。プログラムにより、実行が開始されていない場合には、開始してください。
(gdb) r
プログラムの実行が一時停止されているだけの場合は、再開してください。
(gdb) c
- GDB は、プログラムが指定のシグナルを受信すると実行を停止します。

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.