straceはどのように使用する必要がありますか?


273

ある同僚はかつて、Linuxですべてのデバッグに失敗したときの最後のオプションはstraceを使用することであると私に伝えました。

私はこの奇妙なツールの背後にある科学を学ぼうとしましたが、私はシステム管理の第一人者ではなく、実際に結果を得ることができませんでした。

そう、

  • それは正確には何であり、それは何をしますか?
  • どのように、どのような場合に使用すべきですか?
  • 出力をどのように理解して処理する必要がありますか?

簡単に言えば、簡単な言葉で、どのようにこのようなものに動作しますか?


2
strace -p <pid>は、プログラムで現在行われていることを示します
。GDB

1
個人的にはman straceとても読みやすくて便利だと思います。(PSはLinuxの専門家ではなく、昨日までstraceを知りませんでした)
Alexander Malakhov 14

1
「straceはシステムコールトレーサー」-プログラムの結果として(引数とともに)呼び出されているカーネル関数を表示するだけです。
Pithikos 14

回答:


184

Straceの概要
straceは、軽量のデバッガーと見なすことができます。プログラマー/ユーザーは、プログラムがOSとどのように相互作用しているかをすばやく見つけることができます。これは、システムコールとシグナルを監視することによって行われます。


ソースコードがない場合や、ソースコードを実際に使用することに煩わされたくない場合に使用します。
また、GDBを開いたくないが、外部の相互作用を理解することにのみ興味がある場合は、独自のコードに役立ちます。


先日straceを使用するためのこのイントロに出会った良い少し紹介strace hello world


では、straceが監視するレイヤーの下にあるものを使用するとどうなるでしょうか。
Pacerier 2014年

その場合、@ Pacerierは、ltrace stackoverflow.com
a

存在する/ほとんどの場合にのみ存在する低レベルのプログラムをデバッグして興味深いシステムコールを作成したり、syscallsの新しいオプションを試してOSの動作を確認したりするのに最適です。これは基本的に、1回限りの実験のロギング/エラーチェックコードを書く手間を省きます。(または、誤って間違った引数または呼び出し番号を渡してしまう可能性が高い場所にasmまたは何かで書き込んでいる場合。)straceはGDBよりもはるかに高速です。たとえば、-EFAULT(おっと、読み取り専用) buffer)または-ENOENT(おっと、相対パスが機能しない間違ったディレクトリから実行された))
Peter Cordes

62

簡単に言うと、straceは、プログラムによって発行されたすべてのシステムコールとその戻りコードをトレースします。ファイルやソケットの操作など、もっとあいまいなものを考えてみてください。

ここでのシステムコールは標準のCライブラリコールをより正確に表すため、Cに関する実用的な知識がある場合に最も役立ちます。

あなたのプログラムが/ usr / local / bin / coughであるとしましょう。単に使用:

strace /usr/local/bin/cough <any required argument for cough here>

または

strace -o <out_file> /usr/local/bin/cough <any required argument for cough here>

「out_file」に書き込む。

すべてのstrace出力はstderrに送られます(その大量のボリュームがファイルへのリダイレクトを要求することが多いことに注意してください)。最も単純なケースでは、プログラムはエラーで中止され、OSとの最後のやり取りがstrace出力でどこにあるかを確認できます。

詳細については、以下を参照してください。

man strace

36

straceは、それが適用されるプロセスによって行われたすべてのシステムコールをリストします。システムコールの意味がわからない場合、システムコールから多くの距離を取得することはできません。

それでも、問題がファイルまたはパスまたは環境値に関係している場合、問題のあるプログラムでstraceを実行し、出力をファイルにリダイレクトしてから、そのファイルをパス/ファイル/環境文字列にgrepすることで、プログラムが実際に何を試みているかを確認できます。あなたがそれを期待していたものとは異なるようにしてください。


7
そして、重要なプログラムの場合、これは消防用ホースから飲むようなものであることが多いので、結果を確認するために作業を切り捨てます...
dmckee --- ex-moderator kitten

17
strace <prog_name>プログラムをトレースします。strace -o <out_file> <prog_name>ファイルに出力する
Jestin Joy

8
strace prog 2>&1 | grep ^ open \(
eisbaw

10
または単に:strace -e open myprogまたはすべてのファイル関連のsys呼び出しの場合:strace -e file myprog
Amit Naidu 2013

17

Straceは、デバッガーの下でこれらのプログラムを実行する余裕がない生産システムを調査するためのツールとして際立っています。特に、次の2つの状況でstraceを使用しました。

  • プログラムfooはデッドロック状態のようで、応答しなくなりました。これはgdbのターゲットになる可能性があります。ただし、ソースコードが常にあるとは限らず、デバッガーで実行するのが簡単ではないスクリプト言語を扱っていた場合もあります。この場合、すでに実行中のプログラムでstraceを実行すると、実行中のシステムコールのリストが表示されます。これは、クライアント/サーバーアプリケーションまたはデータベースと対話するアプリケーションを調査する場合に特に役立ちます。
  • プログラムが遅い理由の調査。特に、新しい分散ファイルシステムに移動したばかりで、システムの新しいスループットが非常に低速でした。'-T'オプションを使用してstraceを指定すると、各システムコールで費やされた時間を知ることができます。これは、ファイルシステムが原因で速度が低下する原因を特定するのに役立ちました。

straceを使用した分析の例については、この質問に対する私の回答を参照してください。


15

私はパーミッションの問題をデバッグするために常にstraceを使用しています。テクニックは次のようになります。

$ strace -e trace=open,stat,read,write gnome-calculator

gnome-calculator実行するコマンドはどこにありますか。


8

strace -tfp PIDはPIDプロセスのシステムコールを監視するため、プロセス/プログラムのステータスをデバッグ/監視できます。


6

Straceは、デバッグツールとして、またはプリミティブプロファイラーとして使用できます。

デバッガーとして、特定のシステムコールがどのように呼び出され、実行され、何が返されるかを確認できます。これは、プログラムが失敗したことだけでなく、プログラムが失敗した理由を確認できるため、非常に重要です。通常、これは、プログラムの考えられるすべての結果をキャッチしない、お粗末なコーディングの結果です。それ以外の場合は、ファイルへのハードコーディングされたパスです。straceを使用しないと、どこでどのように問題が発生したかを推測できます。straceを使用すると、syscallの内訳を取得します。通常、戻り値を見るだけで多くのことがわかります。

プロファイリングは別の用途です。これを使用して、各syscallの実行の時間を個別に、または集計として使用できます。これは問題を修正するには十分ではないかもしれませんが、潜在的な容疑者のリストを少なくとも大幅に絞り込みます。1つのファイルに多数のfopen / closeペアが表示される場合は、ループの外側でファイルを開いたり閉じたりするのではなく、ループの実行ごとにファイルを不必要に開いたり閉じたりしている可能性があります。

Ltraceはstraceの親友であり、非常に便利です。あなたはあなたのボトルネックがどこにあるかを区別することを学ぶ必要があります。合計実行時間が8秒で、システムコールに0.05秒しか費やしていない場合、プログラムを分割してもあまり効果はありません。問題はコードにあります。これは通常、論理的な問題であるか、プログラムが実際に必要です実行に長い時間がかかります。

strace / ltraceの最大の問題は、出力の読み取りです。呼び出しがどのように行われるか、または少なくともsyscalls /関数の名前がわからない場合、意味を解読することは困難です。関数が返すものを知ることは、特にさまざまなエラーコードの場合にも非常に有益です。解読するのは面倒ですが、彼らは時々本当に知識の真珠を返します。私がiノードを使い果たしたが、空き領域を使い果たしたわけではないので、通常のユーティリティでは警告が出されず、新しいファイルを作成できませんでした。straceの出力からエラーコードを読み取ると、正しい方向に向かった。


4

Straceは、アプリケーションがオペレーティングシステムとどのように相互作用するかを通知するツールです。

これは、アプリケーションが使用するOSシステムコールと、それを呼び出すパラメーターを通知することによって行われます。

したがって、たとえば、プログラムが開こうとしているファイルを確認し、呼び出しが成功したことを確認できます。

このツールを使用して、あらゆる種類の問題をデバッグできます。たとえば、アプリケーションが、インストールしたことがわかっているライブラリが見つからないと言った場合、straceは、アプリケーションがそのファイルを探している場所を通知します。

そして、それは氷山の一角にすぎません。


これは非常に正確です。
prosti

4

straceは、プログラムがさまざまなシステムコール(カーネルへの要求)を行う方法を学習するための優れたツールであり、失敗したものと、その失敗に関連するエラー値も報告します。すべての失敗がバグであるとは限りません。たとえば、ファイルを検索しようとしているコードはENOENT(そのようなファイルまたはディレクトリはありません)エラーを受け取る可能性がありますが、コードのロジックでは許容可能なシナリオである可能性があります。

straceを使用する1つの良い使用例は、一時ファイルの作成中に競合状態をデバッグすることです。たとえば、特定の文字列にプロセスID(PID)を追加してファイルを作成するプログラムは、マルチスレッドシナリオで問題に直面する可能性があります。[PID + TID(プロセスID +スレッドID)またはmkstempなどのより良いシステムコールでこれを修正します]。

クラッシュのデバッグにも適しています。straceとデバッグクラッシュに関するこの(私の)記事が役に立つかもしれません。


4

最小限の実行可能な例

概念が明確でない場合は、それを説明する、見たことのない簡単な例があります。

この場合、その例はLinux x86_64アセンブリの自立型(libcなし)hello worldです。

こんにちは。

.text
.global _start
_start:
    /* write */
    mov $1, %rax    /* syscall number */
    mov $1, %rdi    /* stdout */
    mov $msg, %rsi  /* buffer */
    mov $len, %rdx  /* buffer len */
    syscall

    /* exit */
    mov $60, %rax   /* exit status */
    mov $0, %rdi    /* syscall number */
    syscall
msg:
    .ascii "hello\n"
len = . - msg

GitHubアップストリーム

組み立てて実行する:

as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out

期待される出力:

hello

次に、その例でstraceを使用します。

env -i ASDF=qwer strace -o strace.log -s999 -v ./hello.out arg0 arg1
cat strace.log

を使用しております:

strace.log 今が含まれています:

execve("./hello.out", ["./hello.out", "arg0", "arg1"], ["ASDF=qwer"]) = 0
write(1, "hello\n", 6)                  = 6
exit(0)                                 = ?
+++ exited with 0 +++

そのような最小限の例では、出力のすべての文字は自明です。

  • execve行:CLI引数と環境を含む、strace実行方法を示します。hello.outman execve

  • writeline:作成した書き込みシステムコールを示します。6文字列の長さです"hello\n"

    = 6記載されてman 2 writeいるように、書き込まれたバイト数であるシステムコールの戻り値です。

  • exitline:実行したexitシステムコールを示します。プログラムが終了したため、戻り値はありません。

より複雑な例

straceの適用はもちろん、プログラムのデバッグ/最適化を支援するために複雑なプログラムが実際に実行しているシステムコールを確認することです。

特に、Linuxで遭遇する可能性が高いほとんどのシステムコールにはglibcラッパーがあり、その多くはPOSIXからのものです。

内部的には、glibcラッパーは多かれ少なかれ次のようにインラインアセンブリを使用します:インラインアセンブリでsysenterを介してシステムコールを呼び出す方法は?

次の例は、POSIX writehello worldです。

main.c

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *msg = "hello\n";
    write(1, msg, 6);
    return 0;
}

コンパイルして実行:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

今回はmain、mainの適切な環境をセットアップする前に、glibcによって一連のシステムコールが行われていることがわかります。

これは、現在、独立したプログラムではなく、libc機能を可能にする、より一般的なglibcプログラムを使用しているためです。

次に、両端に以下strace.logが含まれます。

write(1, "hello\n", 6)                  = 6
exit_group(0)                           = ?
+++ exited with 0 +++

したがって、writePOSIX関数がLinux writeシステムコールを使用していると結論付けました。

またreturn 0exit_groupではなく呼び出しが発生することもわかりexitます。あ、これは知らなかった!これがstraceとてもクールな理由です。man exit_group次に説明します:

このシステムコールは、呼び出しスレッドだけでなく、呼び出しプロセスのスレッドグループ内のすべてのスレッドを終了することを除いて、exit(2)と同等です。

そして、これは私がどのシステムコールがdlopen使用するかを調べた別の例です:https : //unix.stackexchange.com/questions/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

Ubuntu 16.04、GCC 6.4.0、Linuxカーネル4.4.0でテスト済み。


2

以下は、straceを使用してWebサイトを掘り下げる方法の例です。これがお役に立てば幸いです。

最初のバイトまでの時間を次のように確認します。

time php index.php > timeTrace.txt

アクションの何パーセントが何をしているかを確認します。多くlstatとは、fstatそれがキャッシュをクリアする時が来たことを示している可能性があります:

strace -s 200 -c php index.php > traceLstat.txt

trace.txtどのような呼び出しが行われているかを正確に確認できるようにaを出力します。

strace -Tt -o Fulltrace.txt php index.php

何がかかったかどうかを確認するためにこれを使用.1する.9負荷への第二の:

cat Fulltrace.txt | grep "[<]0.[1-9]" > traceSlowest.txt

不足しているファイルやディレクトリがに巻き込まれていないか確認してくださいstrace。これにより、システムに関連する多くのものが出力されます。関連するビットは、お客様のファイルのみです。

strace -vv php index.php 2>&1 | sed -n '/= -1/p' > traceFailures.txt

1

私はそれstraceがあなたのオペレーティングシステムとどのように相互作用するかをチェックすることを読む答えのいくつかが好きでした。

これはまさに私たちが見ることができるものです。システムが呼び出します。比較するstraceltrace、違いはより明白です。

$>strace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        11           close
  0.00    0.000000           0        10           fstat
  0.00    0.000000           0        17           mmap
  0.00    0.000000           0        12           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         9           openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    93        10 total

一方ltrace、トレース機能があります。

$>ltrace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 15.52    0.004946         329        15 memcpy
 13.34    0.004249          94        45 __ctype_get_mb_cur_max
 12.87    0.004099        2049         2 fclose
 12.12    0.003861          83        46 strlen
 10.96    0.003491         109        32 __errno_location
 10.37    0.003303         117        28 readdir
  8.41    0.002679         133        20 strcoll
  5.62    0.001791         111        16 __overflow
  3.24    0.001032         114         9 fwrite_unlocked
  1.26    0.000400         100         4 __freading
  1.17    0.000372          41         9 getenv
  0.70    0.000222         111         2 fflush
  0.67    0.000214         107         2 __fpending
  0.64    0.000203         101         2 fileno
  0.62    0.000196         196         1 closedir
  0.43    0.000138         138         1 setlocale
  0.36    0.000114         114         1 _setjmp
  0.31    0.000098          98         1 realloc
  0.25    0.000080          80         1 bindtextdomain
  0.21    0.000068          68         1 opendir
  0.19    0.000062          62         1 strrchr
  0.18    0.000056          56         1 isatty
  0.16    0.000051          51         1 ioctl
  0.15    0.000047          47         1 getopt_long
  0.14    0.000045          45         1 textdomain
  0.13    0.000042          42         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00    0.031859                   244 total

マニュアルを何度か確認しましたが、名前の由来はわかりませんが、straceシステムコールトレースと思われます。

について言うべき3つの大きなノートがありますstrace

注1:これらの両方の機能straceltraceシステムコールを使用していますptrace。したがって、ptraceシステムコールは効果的に機能しstraceます。

ptrace()システムコールは、あるプロセス(「トレーサ」)が別のプロセス(「トレーサ」)の実行を監視および制御し、トレーサのメモリとレジスタを調べて変更する手段を提供します。主に、ブレークポイントのデバッグとシステムコールトレースを実装するために使用されます。

注2:は非常に冗長になる可能性があるため、straceで使用できるさまざまなパラメーターがありますstrace-c物事の要約のようなものを試してみたい。に基づいて、そのコールのみが表示される-cようなシステムコールを1つ選択できます-e trace=open。これは、トレースしているコマンド中に開かれるファイルを調べている場合に役立ちます。もちろん、grep同じ目的でを使用でき2>&1 | grep etcますが、コマンドが発行されたときに構成ファイルが参照されていることを理解するには、このようにリダイレクトする必要があることに注意してください。

注3:この非常に重要なメモを見つけます。特定のアーキテクチャに限定されません。strace異なるアーキテクチャのバイナリを追跡できるので、あなたは心を打たれるでしょう。 ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.