在 Linux 中调试程序执行的 Strace 示例
【摘要】 Strace 是一个调试工具,可以帮助您解决问题。
Strace 是一个调试工具,可以帮助您解决问题。
Strace 监控特定程序的系统调用和信号。当您没有源代码并想调试程序的执行时,它会很有帮助。strace 为您提供二进制文件从头到尾的执行顺序。
本文解释了 7 个 strace 示例以帮助您入门。
1. 跟踪可执行文件的执行
您可以使用 strace 命令来跟踪任何可执行文件的执行。以下示例显示了 Linux ls 命令的 strace 输出。
$ strace ls
execve("/bin/ls", ["ls"], [/* 21 vars */]) = 0
brk(0) = 0x8c31000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78c7000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=65354, ...}) = 0
...
...
...
2. 使用选项 -e 跟踪可执行文件中的特定系统调用
默认情况下,strace 显示给定可执行文件的所有系统调用。要仅显示特定的系统调用,请使用 strace -e 选项,如下所示。
$ strace -e open ls
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/libselinux.so.1", O_RDONLY) = 3
open("/lib/librt.so.1", O_RDONLY) = 3
open("/lib/libacl.so.1", O_RDONLY) = 3
open("/lib/libc.so.6", O_RDONLY) = 3
open("/lib/libdl.so.2", O_RDONLY) = 3
open("/lib/libpthread.so.0", O_RDONLY) = 3
open("/lib/libattr.so.1", O_RDONLY) = 3
open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
Desktop Documents Downloads examples.desktop libflashplayer.so
Music Pictures Public Templates Ubuntu_OS Videos
上面的输出只显示了 ls 命令的 open 系统调用。在 strace 输出的末尾,它还显示 ls 命令的输出。
如果要跟踪多个系统调用,请使用“-e trace=”选项。以下示例显示了 open 和 read 系统调用。
$ strace -e trace=open,read ls /home
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/libselinux.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\3\3\1\260G004"..., 512) = 512
open("/lib/librt.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\3\3\1\300\30004"..., 512) = 512
..
open("/lib/libattr.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\3\3\1\360\r004"..., 512) = 512
open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3
read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tb"..., 1024) = 315
read(3, "", 1024) = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
open("/home", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
bala
3. 使用选项 -o 将跟踪执行保存到文件
以下示例将 strace 输出存储到 output.txt 文件。
$ strace -o output.txt ls
Desktop Documents Downloads examples.desktop libflashplayer.so
Music output.txt Pictures Public Templates Ubuntu_OS Videos
$ cat output.txt
execve("/bin/ls", ["ls"], [/* 37 vars */]) = 0
brk(0) = 0x8637000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7860000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=67188, ...}) = 0
...
...
4. 使用选项 -p 在正在运行的 Linux 进程上执行 Strace
您可以使用进程 ID 在已经运行的程序上执行 strace。首先,使用ps 命令识别程序的 PID 。
例如,如果要对当前正在运行的 firefox 程序执行 strace,请确定 firefox 程序的 PID。
$ ps -C firefox-bin
PID TTY TIME CMD
1725 ? 00:40:50 firefox-bin
使用如下所示的 strace -p 选项来显示给定进程 ID 的 strace。
$ sudo strace -p 1725 -o firefox_trace.txt
$ tail -f firefox_trace.txt
现在 firefox 进程的执行跟踪将被记录到 firefox_trace.txt 文本文件中。您可以跟踪此文本文件以查看 firefox 可执行文件的实时跟踪。
当您的用户 ID 与给定进程的用户 ID 不匹配时,Strace 将显示以下错误。
$ strace -p 1725 -o output.txt
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
Could not attach to process. If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
5. 使用选项 -t 打印每个跟踪输出行的时间戳
要打印每个 strace 输出行的时间戳,请使用选项 -t,如下所示。
$ strace -t -e open ls /home
20:42:37 open("/etc/ld.so.cache", O_RDONLY) = 3
20:42:37 open("/lib/libselinux.so.1", O_RDONLY) = 3
20:42:37 open("/lib/librt.so.1", O_RDONLY) = 3
20:42:37 open("/lib/libacl.so.1", O_RDONLY) = 3
20:42:37 open("/lib/libc.so.6", O_RDONLY) = 3
20:42:37 open("/lib/libdl.so.2", O_RDONLY) = 3
20:42:37 open("/lib/libpthread.so.0", O_RDONLY) = 3
20:42:37 open("/lib/libattr.so.1", O_RDONLY) = 3
20:42:37 open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3
20:42:37 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
20:42:37 open("/home", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
bala
6. 使用选项 -r 打印系统调用的相对时间
Strace 还可以选择打印每个系统调用的执行时间,如下所示。
$ strace -r ls
0.000000 execve("/bin/ls", ["ls"], [/* 37 vars */]) = 0
0.000846 brk(0) = 0x8418000
0.000143 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
0.000163 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb787b000
0.000119 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
0.000123 open("/etc/ld.so.cache", O_RDONLY) = 3
0.000099 fstat64(3, {st_mode=S_IFREG|0644, st_size=67188, ...}) = 0
0.000155 mmap2(NULL, 67188, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb786a000
...
...
7.使用选项-c生成系统调用的统计报告
使用选项 -c,strace 为执行跟踪提供有用的统计报告。以下输出中的“调用”列指示了该特定系统调用执行了多少次。
$ strace -c ls /home
bala
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
-nan 0.000000 0 9 read
-nan 0.000000 0 1 write
-nan 0.000000 0 11 open
-nan 0.000000 0 13 close
-nan 0.000000 0 1 execve
-nan 0.000000 0 9 9 access
-nan 0.000000 0 3 brk
-nan 0.000000 0 2 ioctl
-nan 0.000000 0 3 munmap
-nan 0.000000 0 1 uname
-nan 0.000000 0 11 mprotect
-nan 0.000000 0 2 rt_sigaction
-nan 0.000000 0 1 rt_sigprocmask
-nan 0.000000 0 1 getrlimit
-nan 0.000000 0 25 mmap2
-nan 0.000000 0 1 stat64
-nan 0.000000 0 11 fstat64
-nan 0.000000 0 2 getdents64
-nan 0.000000 0 1 fcntl64
-nan 0.000000 0 2 1 futex
-nan 0.000000 0 1 set_thread_area
-nan 0.000000 0 1 set_tid_address
-nan 0.000000 0 1 statfs64
-nan 0.000000 0 1 set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 114 10 total
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)