strace命令入门

  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
", 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()创建的子进程。

不断学习中。。。

原文地址:https://www.cnblogs.com/hanerfan/p/5180833.html