291

Linux ですべてのデバッグに失敗した場合の最後のオプションは、 straceを使用することだと同僚が言ったことがあります。

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

そう、

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

簡単に言え、これはどのように機能するのでしょうか?

4

12 に答える 12

196

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


ソースコードを持っていない場合や、わざわざ実際に調べたくない場合に、Good を使用します。
また、GDB を開きたくないが、外部とのやり取りを理解したいだけの場合は、独自のコードに役立ちます。


ちょうど先日、strace の使用に関するこのイントロに出くわしました: strace hello world

于 2008-10-06T16:16:16.297 に答える
65

簡単に言えば、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 に送られます (ファイルの量が多いため、しばしばファイルへのリダイレクトが要求されることに注意してください)。最も単純なケースでは、プログラムはエラーで中止され、strace 出力で OS との最後の対話がどこにあったかを確認できます。

詳細については、次の情報を参照してください。

man strace
于 2008-10-06T16:17:29.273 に答える
38

strace は、適用先のプロセスによって実行されたすべてのシステム コールを一覧表示します。システムコールが何を意味するのかを知らなければ、そこから多くのマイレージを得ることができません。

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

于 2008-10-06T16:11:42.047 に答える
19

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

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

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

于 2008-10-07T05:04:14.017 に答える
16

アクセス許可の問題をデバッグするために、常に strace を使用しています。テクニックは次のようになります。

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

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

于 2015-05-04T15:33:22.080 に答える
8

Strace can be used as a debugging tool, or as a primitive profiler.

As a debugger, you can see how given system calls were called, executed and what they return. This is very important, as it allows you to see not only that a program failed, but WHY a program failed. Usually it's just a result of lousy coding not catching all the possible outcomes of a program. Other times it's just hardcoded paths to files. Without strace you get to guess what went wrong where and how. With strace you get a breakdown of a syscall, usually just looking at a return value tells you a lot.

Profiling is another use. You can use it to time execution of each syscalls individually, or as an aggregate. While this might not be enough to fix your problems, it will at least greatly narrow down the list of potential suspects. If you see a lot of fopen/close pairs on a single file, you probably unnecessairly open and close files every execution of a loop, instead of opening and closing it outside of a loop.

Ltrace is strace's close cousin, also very useful. You must learn to differenciate where your bottleneck is. If a total execution is 8 seconds, and you spend only 0.05secs on system calls, then stracing the program is not going to do you much good, the problem is in your code, which is usually a logic problem, or the program actually needs to take that long to run.

The biggest problem with strace/ltrace is reading their output. If you don't know how the calls are made, or at least the names of syscalls/functions, it's going to be difficult to decipher the meaning. Knowing what the functions return can also be very beneficial, especially for different error codes. While it's a pain to decipher, they sometimes really return a pearl of knowledge; once I saw a situation where I ran out of inodes, but not out of free space, thus all the usual utilities didn't give me any warning, I just couldn't make a new file. Reading the error code from strace's output pointed me in the right direction.

于 2009-08-03T18:21:55.877 に答える
8

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

于 2014-06-19T14:44:31.823 に答える
7

最小限の実行可能な例

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

この場合、その例は 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

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

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

  • exit行: 作成した 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

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

これは、現在、フリースタンディング プログラムではなく、libc 機能を可能にするより一般的な glibc プログラムを使用しているためです。

次に、最後に次のものstrace.logが含まれます。

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

writeしたがって、 POSIX 関数は、驚いたことに、Linuxwriteシステム コールを使用していると結論付けます。

また、 が の代わりに呼び出しにreturn 0つながることもわかります。はー、これは知りませんでした!これがとてもクールな理由です。次に説明します。exit_groupexitstraceman exit_group

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

dlopenそして、これは私がどのシステムコールが使用するかを調べた別の例です:

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

于 2019-03-28T12:07:01.997 に答える
4

Strace は、アプリケーションがオペレーティング システムとどのように対話するかを示すツールです。

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

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

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

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

于 2008-10-06T16:22:19.607 に答える
4

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

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

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

于 2009-08-03T17:27:28.500 に答える
4

strace を使用して Web サイトを掘り下げる方法の例をいくつか示します。これが役に立てば幸いです。

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

time php index.php > timeTrace.txt

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

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

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

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
于 2019-09-17T13:34:05.527 に答える