Linux跟踪系统调用
strace程序
能够截取程序发出的系统调用并且显示它们,被跟踪的程序可以是从strace命令运行的,也可以是系统上已经运行的进程。
例程:
$ strace ./syscalltest2
添加命令行参数-c,在程序执行之后创建一个报告,概述发出的所有系统调用,以及每个系统调用花费的时间)
$ strace -c ./syscalltest2
高级strace参数
参数 | 描述 |
---|---|
-c | 统计每个系统调用的时间、调用和错误(案例:strace -c id) |
-d | 显示strace的一些调试输出 |
-e | 指定输出的过滤表达式,重点分析系统调用(案例:strace -e trace=getpid,getgid ./syscalltest2) |
-f | 在创建子进程的时候跟踪它们 |
-ff | 如果写入到输出文件,则把每个子进程写入到单独的文件中 |
-i | 显示执行系统调用时的指令指针 |
-o | 把输出写入到指定的文件 (案例:strace -o outfile id) |
-p | 附加到由PID指定的现有进程(案例:strace -p 进程号) |
-q | 抑制关于附加和分离的消息 |
-r | 对每个系统调用显示一个相对的时间戳 |
-t | 把时间添加到每一行 |
-tt | 把时间添加到每一行,包括微秒 |
-ttt | 添加epoch形式的时间(从1970年1月1日开始的秒数 |
-T | 显示每个系统调用花费的时间 |
-v | 显示系统调用信息的不经省略的版本 |
-x | 以十六进制格式显示所有非ASCII字符 |
-xx | 以十六进制格式显示所有字符串 |
监视程序系统调用
id命令显示正在运行的程序的当前用户和组ID
dylan@BGY-20190821CDV:~$ id
uid=1000(dylan) gid=1000(dylan) groups=1000(dylan),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),110(lxd)
案例:显示id程序为了执行任务而发出的所有不同的系统调用
dylan@BGY-20190821CDV:~$ strace -c id
uid=1000(dylan) gid=1000(dylan) groups=1000(dylan),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),110(lxd)
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 17 read
0.00 0.000000 0 1 write
0.00 0.000000 0 44 12 open
0.00 0.000000 0 38 close
0.00 0.000000 0 31 fstat
0.00 0.000000 0 28 lseek
0.00 0.000000 0 45 mmap
0.00 0.000000 0 20 mprotect
0.00 0.000000 0 17 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 1 ioctl
0.00 0.000000 0 11 11 access
0.00 0.000000 0 4 socket
0.00 0.000000 0 4 4 connect
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 1 getuid
0.00 0.000000 0 1 getgid
0.00 0.000000 0 1 geteuid
0.00 0.000000 0 1 getegid
0.00 0.000000 0 2 getgroups
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 1 set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 280 29 total
Errors列中,系统调用出现了错误,为了进一步研究
dylan@BGY-20190821CDV:~$ strace -e trace=access,connect id
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
uid=1000(dylan) gid=1000(dylan) groups=1000(dylan),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),110(lxd)
+++ exited with 0 +++
附加到正在运行的程序
只能附加到有权限进行的正在运行的进程,如果正在运行的进程是作为根进程,就必须具有root权限才能进行附加。
dylan@BGY-20190821CDV:~$ ps
PID TTY TIME CMD
4 tty1 00:00:00 bash
2458 tty1 00:00:00 ps
dylan@BGY-20190821CDV:~$ sudo strace -p 4
[sudo] password for dylan:
strace: Process 4 attached