質問

Linux でデバッグにすべてが失敗した場合の最後の選択肢は、ある同僚が私にかつて言ったことです。 .

この奇妙なツールの背後にある科学を学ぼうとしましたが、私はシステム管理の専門家ではないため、あまり結果は得られませんでした。

それで、

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

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

役に立ちましたか?

解決

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

使用
あなたがソースコードを持っていないときや、本当にそれを経験することに煩わされたくないときに適しています。
また、GDBを開くつもりはないが、外部の相互作用を理解したいだけの場合は、独自のコードに役立ちます。

良い紹介
先日straceを使用するためにこのイントロに遭遇しました: strace hello world

他のヒント

簡単に言えば、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

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

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

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

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

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

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

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

gnome-calculator は、実行するコマンドです。

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

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

デバッガとして、特定のシステム コールがどのように呼び出され、実行され、何を返したかを確認できます。これは、プログラムが失敗したことだけでなく、なぜプログラムが失敗したかを確認できるため、非常に重要です。通常、これは、プログラムの考えられるすべての結果を捉えていない、お粗末なコーディングの結果にすぎません。ファイルへのパスがハードコーディングされているだけの場合もあります。痕跡がなければ、何がどこでどのように間違っていたのかを推測することになります。strace を使用すると、システムコールの内訳がわかります。通常は戻り値を見るだけで多くのことがわかります。

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

Ltrace は strace に近いもので、これも非常に便利です。ボトルネックがどこにあるのかを見分ける方法を学ばなければなりません。合計実行時間が 8 秒で、システム コールに 0.05 秒しか費やしていない場合、プログラムのストレーシングはあまり役に立ちません。問題はコード内にあり、通常はロジックの問題であるか、プログラムが実際に必要とするものです。走るのにそんなに時間がかかるとは。

strace/ltrace の最大の問題は、出力の読み取りです。呼び出しがどのように行われるか、または少なくともシステムコール/関数の名前がわからない場合、意味を解読するのは困難になります。関数が何を返すかを知ることは、特にさまざまなエラー コードの場合に非常に有益です。解読するのは骨が折れますが、時には本当に知識の真珠が戻ってきます。一度、inode が不足しているが、空き領域が不足しているという状況を見たことがあります。そのため、通常のユーティリティはすべて警告を表示せず、新しいファイルを作成できませんでした。strace の出力からエラー コードを読み取ると、正しい方向が示されました。

Straceは、アプリケーションがオペレーティングシステムと対話する方法を示すツールです。

これは、アプリケーションが使用するOSシステム呼び出しと、それらが呼び出すパラメーターを指定することでこれを行います。

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

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

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

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

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

また、クラッシュのデバッグにも適しています。 straceとデバッグクラッシュに関するこの(私の)記事をご覧ください。便利です。

オペレーティングシステムとの対話方法をチェックする strace を読む回答のいくつかが気に入りました。

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

<*>gt;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
gt;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 があります。

<*>

マニュアルを何度かチェックしましたが、 strace という名前の由来は見つかりませんでしたが、システムコールトレースである可能性が高いのは明らかです。

strace について3つの大きなメモがあります。

注1:これらの関数 strace ltrace は両方とも、システムコール ptrace 。したがって、 ptrace システムコールは、 strace の効果的な方法です。

  

ptrace()システムコールは、1つのプロセス(          &quot; tracer&quot;)は、別のプロセスの実行を監視および制御できます          (&quot; tracee&quot;)、トレースのメモリを調べて変更し、          レジスタ。主にブレークポイントのデバッグを実装するために使用されます          およびシステムコールのトレース。

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

注3:この非常に重要な注を見つけました。特定のアーキテクチャに限定されません。 strace は、さまざまなアーキテクチャのバイナリをトレースできるため、気が遠くなります。 ここに画像の説明を入力してください

最小限の実行可能な例

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

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

hello.S

.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 
as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out
, %rdi /* syscall number */ syscall msg: .ascii "hello\n" len = . - msg

GitHubアップストリーム

アセンブルして実行:

hello

期待される出力:

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

今、その例でstraceを使用しましょう。

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

使用:

strace.log に次が含まれるようになりました:

#define _XOPEN_SOURCE 700
#include <unistd.h>

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

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

  • execve 行: manで文書化されているCLI引数と環境を含む strace hello.out を実行した方法を示しますexecve

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

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

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

より複雑な例

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

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

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

次に学習すべき例は、POSIX write hello worldです:

main.c

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

コンパイルして実行:

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

今回は、 main の前にglibcによって一連のシステムコールが行われ、mainの環境を整えていることがわかります。

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

その後、すべての終わりに、 strace.log には以下が含まれます。

<*>

したがって、 write POSIX関数は、Linuxの write システムコールを使用していると思います。

また、 return 0 exit ではなく exit_group の呼び出しにつながることも確認しています。ハ、私はこれについて知りませんでした!これが 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カーネルでテスト済み

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top