strace 是一个常用的linux命令,应该是 trace system calls的简写形式,用来追踪一个程序的系统调用。
1、启动并跟踪程序
strace ./test.exe ## 结果打印在屏幕
strace -o out.txt ./test.exe ## 结果输出在文件
strace -f -o out.txt ./test.exe ## -f 表示跟踪子进程
2、跟踪shell命令
其实和1类似:
[KentZhang@LOCAL-192-168-97-2 cpp_demo]$ strace ls ## 跟踪ls命令
execve("/bin/ls", ["ls"], [/* 25 vars */]) = 0
brk(0) = 0xc8d000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5fae3c5000
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=54632, ...}) = 0
mmap(NULL, 54632, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5fae3b7000
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\0PY\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=122056, ...}) = 0
3、追踪运行的进程
strace -p $pid
[KentZhang@LOCAL-192-168-97-2 cpp_demo]$ strace -p 19305
Process 19305 attached
futex(0x7fdeb8ffb9d0, FUTEX_WAIT, 19306, NULL
4、统计系统调用的信息
strace -c [程序或者命令]
[KentZhang@LOCAL-192-168-97-2 cpp_demo]$ strace -c ls
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000020 1 28 mmap
0.00 0.000000 0 10 read
0.00 0.000000 0 2 write
0.00 0.000000 0 12 open
0.00 0.000000 0 14 close
0.00 0.000000 0 12 fstat
0.00 0.000000 0 16 mprotect
0.00 0.000000 0 3 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 1 statfs
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 2 1 futex
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 1 set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00 0.000020 117 2 total
每一列的含义:
所占时间的百分比 一共消耗的时间 一次调用消耗的时间(单位 微秒) 调用次数 出错次数 调用名称
5、跟踪指定的系统调用
-e trace=read ## 跟踪read系统调用
-e trace=file ## 跟踪有关文件操作的系统调用
-e trace=process ## 跟踪有关进程控制的系统调用
-e trace=network ## 跟踪与网络有关的所有系统调用
-e trace=ipc ## 跟踪进程通信有关的系统调用
## 跟踪read系统调用
[KentZhang@LOCAL-192-168-97-2 cpp_demo]$ strace -e trace=read df
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\356\1\0\0\0\0\0"..., 832) = 832
read(3, "/dev/sda2 / ext4 rw 0 0\nproc /pr"..., 4096) = 312
read(3, "", 4096) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2512
read(3, "", 4096) = 0
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 51475068 29970200 18883428 62% /
tmpfs 66059396 16 66059380 1% /dev/shm
/dev/sda1 999320 68336 878556 8% /boot
/dev/sda4 491806744 405585820 61231844 87% /data
/dev/sdb1 2307222740 74280 2189941600 1% /disk1
+++ exited with 0 +++
## 跟踪有关文件操作的系统调用
[KentZhang@LOCAL-192-168-97-2 cpp_demo]$ strace -e trace=file df
execve("/bin/df", ["df"], [/* 25 vars */]) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib64/libc.so.6", O_RDONLY) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
open("/etc/mtab", O_RDONLY|O_CLOEXEC) = 3
statfs("/", {f_type="EXT2_SUPER_MAGIC", f_bsize=4096,
## 跟踪有关进程控制的系统调用
[KentZhang@LOCAL-192-168-97-2 cpp_demo]$ strace -e trace=process date
execve("/bin/date", ["date"], [/* 25 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f18b3be2700) = 0
Thu Nov 29 00:08:49 CST 2018
exit_group(0) = ?
+++ exited with 0 +++
## 跟踪与网络有关的所有系统调用
[KentZhang@LOCAL-192-168-97-2 cpp_demo]$ strace -e trace=network ping 192.168.97.2
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = -1 EPERM (Operation not permitted)
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("192.168.97.2")}, 16) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(63882), sin_addr=inet_addr("192.168.97.2")}, [16]) = 0
ping: icmp open socket: Operation not permitted
+++ exited with 2 +++