9.2. strace の使用
分析するプログラムで strace
ユーティリティーを実行するには、次のコマンドを実行します。
$ scl enable devtoolset-12 'strace program argument...'
program を、分析するプログラムの名前に置き換え、argument を、このプログラムに指定するコマンドラインオプションと引数に置き換えます。以下の例では、-p
コマンドラインオプションとプロセス ID を使用して、実行中のプロセスでユーティリティーを実行できます。
$ scl enable devtoolset-12 'strace -p process_id'
この scl
ユーティリティーを使用してコマンドを実行すると、これを Red Hat Enterprise Linux システムに優先して使用する Red Hat Developer Toolset バイナリーで実行することができることに注意してください。これにより、デフォルトで Red Hat Developer Toolset strace
でシェルセッションを実行できます。
$ scl enable devtoolset-12 'bash'
任意の時点で使用している strace
のバージョンを確認するには、以下のコマンドを実行します。
$ which strace
Red Hat Developer Toolset の strace
実行可能なパスは、/opt
で始まります。以下のコマンドを使用して、バージョン番号が Red Hat Developer Toolset strace
と一致することを確認することができます。
$ strace -V
9.2.1. 出力のファイルへのリダイレクト
デフォルトでは strace
、各システムコールの名前、引数、および戻り値を標準エラー出力に出力します。この出力をファイルにリダイレクトするには、-o
コマンドラインオプションの後にファイル名を指定します。
$ scl enable devtoolset-12 'strace -o file_name program argument...'
file_name をファイル名に置き換えます。
例9.1 出力のファイルへのリダイレクト
例8.1「デバッグ情報を使用した C プログラムのコンパイル」 から fibonacci
ファイルのバージョンを若干変更したことを検討してください。この実行可能ファイルには、Fibonacci シーケンスが表示され、オプションでこのシーケンスのメンバー数を指定することができます。このファイルで strace
ユーティリティーを実行し、トレース出力を fibonacci.log
リダイレクトします。
$ scl enable devtoolset-12 'strace -o fibonacci.log ./fibonacci 20'
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
これにより、現在の作業ディレクトリーに、fibonacci.log
という新しいプレーンテキストファイルが作成されます。
9.2.2. 選択したシステム呼び出しの追跡
選択したシステムコールのセットのみを追跡するには、strace
コマンドラインオプションを指定して -e
ユーティリティーを実行します。
$ scl enable devtoolset-12 'strace -e expression program argument...'
expression を、トレースするシステムコールのコンマ区切りリスト、または 表9.1「-e オプションで一般的に使用される値」 にリストされているにキーワードに置き換えます。使用できるすべての値の説明は、strace(1) の man ページを参照してください。
値 | 説明 |
---|---|
| ファイル名を引数として受け入れるシステムコール。 |
| プロセス管理に関連するシステムコール。 |
| ネットワークに関連するシステムコール。 |
| シグナル管理に関連するシステムコール。 |
| IPC (inter-process communication) に関連するシステムコール。 |
| ファイル記述子に関連するシステムコール。 |
構文 -e 式
は、完全な形式の -e trace=式
です。
例9.2 選択したシステム呼び出しの追跡
例11.1「memstomp の使用」 の employee
ファイルを考慮します。この実行可能ファイルで strace
ユーティリティーを実行し、mmap
および munmap
システムコールのみをトレースします。
$ scl enable devtoolset-12 'strace -e mmap,munmap ./employee'
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f896c744000
mmap(NULL, 61239, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f896c735000
mmap(0x3146a00000, 3745960, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3146a00000
mmap(0x3146d89000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x189000) = 0x3146d89000
mmap(0x3146d8e000, 18600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3146d8e000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f896c734000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f896c733000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f896c732000
munmap(0x7f896c735000, 61239) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f896c743000
John,john@example.comDoe,
+++ exited with 0 +++
9.2.3. タイムスタンプの表示
トレースの各行を、時間、分、および秒で正確な時刻に接頭辞するには、-t
コマンドラインオプションを指定して strace
ユーティリティーを実行します。
$ scl enable devtoolset-12 'strace -t program argument...'
ミリ秒を表示するには、-t
オプションを 2 回指定します。
$ scl enable devtoolset-12 'strace -tt program argument...'
トレースの各行を、各システムコールの実行に必要な時間に接頭辞を付けるには、-r
コマンドラインオプションを使用します。
$ scl enable devtoolset-12 'strace -r program argument...'
例9.3 タイムスタンプの表示
pwd
という名前の実行ファイルを考慮してください。このファイルで strace
ユーティリティーを実行し、出力にタイムスタンプを含めます。
$ scl enable devtoolset-12 'strace -tt pwd'
19:43:28.011815 execve("./pwd", ["./pwd"], [/* 36 vars */]) = 0
19:43:28.012128 brk(0) = 0xcd3000
19:43:28.012174 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc869cb0000
19:43:28.012427 open("/etc/ld.so.cache", O_RDONLY) = 3
19:43:28.012446 fstat(3, {st_mode=S_IFREG|0644, st_size=61239, ...}) = 0
19:43:28.012464 mmap(NULL, 61239, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc869ca1000
19:43:28.012483 close(3) = 0
...
19:43:28.013410 +++ exited with 0 +++
9.2.4. サマリーの表示
各システムコールの実行に必要な時間、これらのシステムコールが実行した回数、実行中に発生したエラー数の概要を表示するには、-c
コマンドラインオプションを指定して strace
ユーティリティーを実行します。
$ scl enable devtoolset-12 'strace -c program argument...'
例9.4 サマリーの表示
lsblk
という名前の実行ファイルを考慮してください。このファイルで strace
ユーティリティーを実行し、トレースの概要を表示します。
$ scl enable devtoolset-12 'strace -c lsblk > /dev/null'
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
80.88 0.000055 1 106 16 open
19.12 0.000013 0 140 munmap
0.00 0.000000 0 148 read
0.00 0.000000 0 1 write
0.00 0.000000 0 258 close
0.00 0.000000 0 37 2 stat
...
------ ----------- ----------- --------- --------- ----------------
100.00 0.000068 1790 35 total
9.2.5. システムコール結果の改ざん
システムコールから返されたエラーをシミュレートすると、プログラムで不足しているエラー処理の特定に役立ちます。
特定のシステムコールの結果としてプログラムが一般的なエラーを受け取るには、-e fault=
オプションを指定して strace
ユーティリティーを実行し、システムコールを指定します。
$ scl enable devtoolset-12 'strace -e fault=syscall program argument...'
エラーの種類または戻り値を指定するには、-e inject=
オプションを使用します。
$scl enable devtoolset-12 'strace -e inject=syscall:error=error-type program argument'
$scl enable devtoolset-12 'strace -e inject=syscall:retval=return-value program argument'
エラータイプと戻り値は相互排他的であることに注意してください。
例9.5 システムコール結果の改ざん
lsblk
という名前の実行ファイルを考慮してください。このファイルで strace
ユーティリティーを実行すると、mmap()
システムコールがエラーを返すようにします。
$ scl enable devtoolset-12 'strace -e fault=mmap:error=EPERM lsblk > /dev/null'
execve("/usr/bin/lsblk", ["lsblk"], 0x7fff1c0e02a0 /* 54 vars */) = 0
brk(NULL) = 0x55d9e8b43000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 EPERM (Operation not permitted) (INJECTED)
writev(2, [{iov_base="lsblk", iov_len=5}, {iov_base=": ", iov_len=2}, {iov_base="error while loading shared libra"..., iov_len=36}, {iov_base=": ", iov_len=2}, {iov_base="", iov_len=0}, {iov_base="", iov_len=0}, {iov_base="cannot create cache for search p"..., iov_len=35}, {iov_base=": ", iov_len=2}, {iov_base="Cannot allocate memory", iov_len=22}, {iov_base="\n", iov_len=1}], 10lsblk: error while loading shared libraries: cannot create cache for search path: Cannot allocate memory
) = 105
exit_group(127) = ?
+++ exited with 127 +++