萌えハッカーニュースリーダー

2025/06/14 07:20 Strace Tips for Better Debugging

出典:

strace tips for better debugging

Recently, I have been building software without libc to better understand Linux syscalls and internals better. So far, I have built a minimal shell, terminal Snake game, pure ARM64 assembly HTTP server and threads implementation. I have been using strace extensively while debugging. Useful options and flags I use a version of the following command: strace -fintrCDTYyy -o strace.log -v -s128 ./binary This looks like an alphabet soup of options! Here’s what they do and how they are useful: -f: Follow child processes/threads. This is especially useful when dealing with spawning processes or threads as otherwise, strace will only trace the parent process. -v: Print unabbreviated versions of environment, stat, termios and other structs in syscalls. I found this invaluable in conjunction with -s when doing assembly programming to check if the structs were being initialized correctly and if certain arguments were being sent in little/big endian format -s NUM: Specify the maximum string size to print. Useful for large structs -o: Save strace output to a log file. It is always better to do this to investigate the output of the original process and strace separately without each cluttering the other -yy: Print all available information associated with file descriptors. This is great for expanding the file descriptor to either its full path in case of a file or TCP address in case of sockets -Y: Print command names for PIDs. I found this useful when building the shell to check if the correct program is being executed -t: Print current timestamp in log -T: Show time spent in syscalls. Useful for some basic profiling although strace heavily slows down the process. -r: Print a relative timestamp upon entry to each system call -n: Print syscall number. Great to quickly find out syscall numbers on new architectures. -i: Print instruction pointer at the time of syscall. Found this useful when debugging assembly code to check rough location of errors. -C: Print summary of syscall count, time, errors at the end of regular output Print stack traces The -k or --stack-trace prints the stacktrace along with the syscall. This is useful if your program is compiled with with -g. This post is a good read on using strace to show backtraces for a Golang program compiled with GODEBUG.

A Random Walk
hakase
博士

ロボ子、今日は`strace`について話すのじゃ!libcなしでソフトウェアを構築した筆者さんが、デバッグに`strace`を使い倒したらしいぞ。

roboko
ロボ子

libcなしでソフトウェアを構築…すごいですね!`strace`はシステムコールを追跡するツールでしたっけ。どんなオプションが便利なんですか?

hakase
博士

`strace`はシステムコールを監視して、プログラムの動きを理解するのに役立つツールじゃ。特に便利なオプションはたくさんあるぞ!例えば、`-f`は子プロセスも追跡できるし、`-v`は詳細な情報を表示してくれる。

roboko
ロボ子

`strace -f`は、プロセスがfork()やclone()で子プロセスを作るときに便利ですね。`-v`は、構造体の内容を確認するときに役立ちそうです。

hakase
博士

そうじゃ!アセンブリでプログラミングするとき、構造体が正しく初期化されているか、エンディアンが正しいかを確認するのに`-v`はめっちゃ使えるぞ。`-s NUM`で出力する文字列の最大サイズを指定できるのも便利じゃ。

roboko
ロボ子

大きな構造体を扱うときに、`-s`は必須ですね。他にはどんなオプションがありますか?

hakase
博士

`strace -yy`はファイル記述子に関する情報を詳しく表示してくれるし、`-Y`はPIDのコマンド名を表示してくれる。シェルを作るときに、正しいプログラムが実行されているか確認するのに役立つらしい。

roboko
ロボ子

`strace -Y`は、どのプロセスがどのコマンドを実行しているか一目でわかるので、便利そうですね。`-t`でタイムスタンプ、`-T`でsyscallにかかった時間もわかるんですね。

hakase
博士

`strace -T`は基本的なプロファイリングに使えるけど、`strace`自体がプロセスを遅くするから注意が必要じゃ。`-r`で相対的なタイムスタンプ、`-n`でsyscall番号も出力できるぞ。

roboko
ロボ子

`strace -n`は、新しいアーキテクチャでsyscall番号を調べるときに便利ですね。`-i`で命令ポインタも出力できるんですね。

hakase
博士

`strace -i`はアセンブリコードのデバッグに役立つぞ。エラーのおおよその位置を特定できる。`-C`を使うと、syscallのカウント、時間、エラーの要約を最後にまとめて表示してくれる。

roboko
ロボ子

最後にサマリを出してくれるのは便利ですね!スタックトレースを出力するオプションもあるんですね。

hakase
博士

`strace -k`または`--stack-trace`を使うと、syscallと一緒にスタックトレースを出力できる。プログラムを`-g`でコンパイルする必要があるけどな。

roboko
ロボ子

デバッグ情報がないとダメなんですね。特定のsyscallだけをトレースすることもできるんですか?

hakase
博士

もちろんじゃ!`-e`オプションを使うと、syscallのファミリーを選択的にトレースできる。例えば、`-e t=%net`はネットワーク関連のsyscallだけをトレースする。

roboko
ロボ子

`%net`や`%mem`でsyscallをグループ化できるんですね。成功または失敗したsyscallだけをトレースすることもできるんですか?

hakase
博士

`strace -z`で成功したsyscallのみ、`-Z`で失敗したsyscallのみをトレースできるぞ。`-P`オプションは、特定のパスにアクセスするsyscallのみをトレースする。

roboko
ロボ子

`strace -P /usr/bin/ls sh -c ls`のように使うんですね。特定のファイルに対する操作を監視したいときに便利そうです。

hakase
博士

さらにすごいのは、`strace`はsyscallを改ざんできることじゃ!`-e inject`を使うと、特定のsyscallにエラーを注入したり、値を返させたり、シグナルを送信したりできる。

roboko
ロボ子

ええっ!そんなことまでできるんですか!例えば、どんなことができるんですか?

hakase
博士

`strace -e inject=%file:error=ENOENT:when=3+ ls`は、3回成功した後、すべてのファイル関連のsyscallを失敗させる。エラーケースのデバッグにめっちゃ役立つぞ。

roboko
ロボ子

それはすごい!ファイルが存在しない場合のエラー処理をテストするときに使えそうですね。`INJECTED`とマークされることで、注入されたエラーだとわかるんですね。

hakase
博士

その通り!`strace`は、まるで魔法の杖じゃな。でも、使いすぎるとプログラムが遅くなるから、ほどほどにするのじゃぞ!

roboko
ロボ子

了解です、博士!`strace`を使いこなして、デバッグスキルを向上させます!

hakase
博士

そういえばロボ子、`strace`って、ストレースって読むか、ストラッセって読むか、いつも迷うのじゃ…って、どうでもいいか!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search