Strace是一个能帮助你解决问题的debugging工具
Strace监控指定程序系统调用和信号,在你没有源代码又想dubug程序的执行时是会用到的。Strace会以程序的开始到结束来顺序执行的
你可以从这个7个Strace 例子开始起步了解Strace
你可以使用strace命令的跟踪任何可执行程序,接下来的例子展示linux ls命令的的strace输出
[tony@oc4443573018 python]$ strace ls execve("/bin/ls", ["ls"], [/* 52 vars */]) = 0 brk(0) = 0x2172000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5c88a90000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=99825, ...}) = 0 mmap(NULL, 99825, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5c88a77000 close(3) = 0 open("/lib64/libselinux.so.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320X\340\366=\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=124624, ...}) = 0 mmap(0x3df6e00000, 2221912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3df6e00000 mprotect(0x3df6e1d000, 2093056, PROT_NONE) = 0 mmap(0x3df701c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x3df701c000 mmap(0x3df701e000, 1880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3df701e000 close(3) = 0 open("/lib64/librt.so.1", O_RDONLY) = 3 ..... .....
2.使用option -e参数来追踪执行指定程序的系统调用
默认情况下,strace展示指定可执行程序的所有系统调用,使用strace -e选项只输出指定系统调用
[tony@oc4443573018 Videos]$ strace -e open ls open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib64/libselinux.so.1", O_RDONLY) = 3 open("/lib64/librt.so.1", O_RDONLY) = 3 open("/lib64/libcap.so.2", O_RDONLY) = 3 open("/lib64/libacl.so.1", O_RDONLY) = 3 open("/lib64/libc.so.6", O_RDONLY) = 3 open("/lib64/libdl.so.2", O_RDONLY) = 3 open("/lib64/libpthread.so.0", O_RDONLY) = 3 open("/lib64/libattr.so.1", O_RDONLY) = 3 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3 open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 Webcam [tony@oc4443573018 Videos]$
The above output displays only the open system call of the ls command. At the end of the strace output, it also displays the output of the ls command.
上面只输出指定ls命令的系统调用,在strace输出的最后面同时也输出了ls命令的结果
If you want to trace multiple system calls use the “-e trace=” option. The following example displays both open and read system calls.
如果想trace多个系统调用,可以使用"-e strace="选项,下面展示了open和read命令的系统调用
[tony@oc4443573018 ~]$ strace -e trace=open,read ls /home open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib64/libselinux.so.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320X\340\366=\0\0\0"..., 832) = 832 open("/lib64/librt.so.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@! \366=\0\0\0"..., 832) = 832 open("/lib64/libcap.so.2", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\23`\371=\0\0\0"..., 832) = 832 open("/lib64/libacl.so.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\36`\2>\0\0\0"..., 832) = 832 open("/lib64/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\356!\365=\0\0\0"..., 832) = 832 open("/lib64/libdl.so.2", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r\340\365=\0\0\0"..., 832) = 832 open("/lib64/libpthread.so.0", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340]\240\365=\0\0\0"..., 832) = 832 open("/lib64/libattr.so.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\23 \6>\0\0\0"..., 832) = 832 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3 open("/home", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 interpel tonyb [tony@oc4443573018 ~]$
3.使用参数-o 保存strace结果
The following examples stores the strace output to output.txt file.
下面的列子展示strace命令输出的output.txt文件
[tonyboob@oc4443573018 ~]$ strace -o output.txt ls A output.txt a_b.py packages a.py pexpect_test.py B Pictures bianli.py Public C putty.log chefdk-0.10.0-1.el6.x86_64.rpm python CROSS_TEAM Recycle Bin derby.log redis Desktop redis_daemon.sh Documents rpmbuild Downloads SametimeRooms 。。。。。。。。 。。。。。。。。。。 [tony@oc4443573018 ~]$ cat output.txt execve("/bin/ls", ["ls"], [/* 53 vars */]) = 0 brk(0) = 0x1dd9000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f75f6d17000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=99825, ...}) = 0 mmap(NULL, 99825, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f75f6cfe000 close(3) = 0 open("/lib64/libselinux.so.1", O_RDONLY) = 3
4.使用-p 参数来strace一个运行中进程
You could execute strace on a program that is already running using the process id. First, identify the PID of a program using ps command.
可以使用已运行程序PID来strace一个程序,但首先你的使用ps命令来确定PID
For example, if you want to do strace on the firefox program that is currently running, identify the PID of the firefox program.
比如,你想strace运行中的Firefox,先确定Firefox的PID
[tony@oc4443573018 ~]$ ps -C firefox PID TTY TIME CMD 6970 ? 06:02:51 firefox [tony@oc4443573018 ~]$
使用-p选项来展示指定PID输出
[tony@oc4443573018 ~]$ strace -p 6970 -o firefox_strace.txt Process 6970 attached - interrupt to quit ^CProcess 6970 detached [tony@oc4443573018 ~]$ tail -f firefox_strace.txt read(28, "\372", 1)
firefox_trace中将记录firefox进程的trace记录,可以使用tail 命令的动态的观察firefox的输出,不过这是需要在另一个terminal来tail -f的
Strace会显示下面的错误,当你的user id不匹配给定的进程的UID
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参数为每行trace输出打印时间戳
tony@oc4443573018 ~]$ strace -t -e open ls /home 10:43:25 open("/etc/ld.so.cache", O_RDONLY) = 3 10:43:25 open("/lib64/libselinux.so.1", O_RDONLY) = 3 10:43:25 open("/lib64/librt.so.1", O_RDONLY) = 3 10:43:25 open("/lib64/libcap.so.2", O_RDONLY) = 3 10:43:25 open("/lib64/libacl.so.1", O_RDONLY) = 3 10:43:25 open("/lib64/libc.so.6", O_RDONLY) = 3 10:43:25 open("/lib64/libdl.so.2", O_RDONLY) = 3 10:43:25 open("/lib64/libpthread.so.0", O_RDONLY) = 3 10:43:25 open("/lib64/libattr.so.1", O_RDONLY) = 3 10:43:25 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3 10:43:25 open("/home", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 interpel tony
6.使用-r参数打印相关系统调用次数
[tony@oc4443573018 ~]$ strace -r ls 0.000000 execve("/bin/ls", ["ls"], [/* 53 vars */]) = 0 0.000653 brk(0) = 0x1a0b000 0.000141 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdecabb8000 0.000163 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 0.000423 open("/etc/ld.so.cache", O_RDONLY) = 3 0.000895 fstat(3, {st_mode=S_IFREG|0644, st_size=99825, ...}) = 0 0.000136 mmap(NULL, 99825, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fdecab9f000 0.000090 close(3) = 0 0.000111 open("/lib64/libselinux.so.1", O_RDONLY) = 3 0.000816 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320X\340\366=\0\0\0"..., 832) = 832 0.000089 fstat(3, {st_mode=S_IFREG|0755, st_size=124624, ...}) = 0 0.000115 mmap(0x3df6e00000, 2221912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3df6e00000 。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。。。
7.使用-c参数来生成系统调用的统计报告
使用-c选项会提供有用的执行追踪统计报告,下面输出中calls列表明特定的系统被执行了多少次
[tony@oc4443573018 python]$ strace -c ls /home interpel tony % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 98.97 0.000671 61 11 open 1.03 0.000007 0 27 mmap 0.00 0.000000 0 8 read 0.00 0.000000 0 1 write 0.00 0.000000 0 13 close 0.00 0.000000 0 2 stat 0.00 0.000000 0 11 fstat 0.00 0.000000 0 16 mprotect 0.00 0.000000 0 2 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 1 1 access 0.00 0.000000 0 1 execve 0.00 0.000000 0 1 fcntl 0.00 0.000000 0 2 getdents 0.00 0.000000 0 1 getrlimit 0.00 0.000000 0 2 statfs
原文:http://www.cnblogs.com/myland/p/5209179.html