1、strace:trace system calls and signals
1)简介:strace拦截并记录进程调用的系统调用,以及进程收到的信号。它是一个非常有用的程序诊断和调试工具。
2)用法:
(1)示例1:
int main() { std::cout << "hello world" << std::endl; return 0; }
编译成a.out之后,再执行strace -T -tt ./a.out > /dev/null(防止a.out和strace的输出产生混淆),以下是其输出:
12:38:36.908803 execve("./a.out", ["./a.out"], [/* 28 vars */]) = 0 <0.000285> 12:38:36.909372 brk(0) = 0x1127000 <0.000062> 12:38:36.909528 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6ce17d9000 <0.000089> 12:38:36.909784 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) <0.000076> ... ... 12:38:36.918265 write(1, "hello world\n", 12) = 12 <0.000055> 12:38:36.918434 exit_group(0) = ? 12:38:36.918573 +++ exited with 0 +++
可见,关于系统调用的每一行会打印名称、参数和返回值(出错时还有相应的出错字符串)。strace默认在标准出错上打印这些信息。
选项:-T:显示每个系统调用耗费的时间;-t:在每行前面加上时间(-tt:包含微秒)。
执行strace -c ./a.out > /dev/null,以下是其输出:
% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 34.50 0.000069 4 17 mmap 24.00 0.000048 10 5 open 16.00 0.000032 3 10 mprotect 8.00 0.000016 4 4 read 6.00 0.000012 2 6 fstat 5.50 0.000011 2 5 close 4.00 0.000008 8 1 1 access 1.00 0.000002 2 1 execve 0.50 0.000001 1 1 write 0.50 0.000001 1 1 brk 0.00 0.000000 0 1 munmap 0.00 0.000000 0 1 1 ioctl 0.00 0.000000 0 1 arch_prctl ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000200 54 2 total
选项:-c:统计每个系统调用的总次数、总耗时和总出错次数等,在程序退出时输出。在Linux上,这些时间是系统时间(system time,即CPU运行在内核上的时间)。
(2)示例2:
int main() { sleep(100); return 0; }
编译成a.out之后,在终端A执行;在终端B执行strace -p `pidof a.out`。在终端A上把a.out进程切到后台(Ctrl-z),再切回来(fg),可看到终端B的输出(进程收到的信号的信息):
Process 8885 attached restart_syscall(<... resuming interrupted call ...> ) = ? ERESTART_RESTARTBLOCK (Interrupted by signal) --- SIGTSTP {si_signo=SIGTSTP, si_code=SI_KERNEL, si_value={int=3722471000, ptr=0x7f6fdde06658}} --- --- stopped by SIGTSTP --- --- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=2455, si_uid=0} --- restart_syscall(<... resuming interrupted call ...>
选项:-p:attach到指定PID的进程上(多个-p可attach到多个进程)。
3)其他选项:-f:追踪当前进程通过fork()/vfork()/clone()创建的子进程。
不断学习中。。。