在操作系统运维中会出现程序或系统命令运行失败,通过报错和日志无法定位问题根本原因

比如keepalive脚本执行失败,但是体现在日志中是其他提示,没有相关报错

如何在没有内核或程序代码的情况下查看系统调用的进程

strace工具介绍

  • strace是一个非常有用的诊断、说明和调试工具,Linux系统管理员可以在不需要源代码的情况下即可跟踪系统调用情况
  • strace显示有关进程的系统调用的信息,这可以帮助确定一个程序使用的哪个函数,当然在系统出现问题时可以使用strace定位系统调用过程中失败的原因,这是定位系统问题的很好的解决办法

参数解析

  • -c

    统计每一体统调用所执行的时间,次数和出错的次数等

    例如:打印执行uptime时系统调用的时间、次数、出错次数和syscall

    1
    # strace -c uptime 
    2
     11:05:10 up 42 min,  3 users,  load average: 0.24, 0.14, 0.14
    3
    % time     seconds  usecs/call     calls    errors syscall
    4
    ------ ----------- ----------- --------- --------- ----------------
    5
     27.11    0.000247           3        67           mmap
    6
     26.45    0.000241           3        61        30 open
    7
     19.98    0.000182           4        44           mprotect
    8
      7.79    0.000071           2        29           fstat
    9
      6.70    0.000061           1        37           read
    10
      4.94    0.000045           1        31           close
    11
      2.20    0.000020           2         9         7 stat
    12
      0.99    0.000009           0        21           alarm
    13
      0.88    0.000008           0        16           rt_sigaction
    14
      0.77    0.000007           0        14           fcntl
    15
      0.55    0.000005           1         4         3 access
    16
      0.44    0.000004           4         1           write
    17
      0.33    0.000003           0         6           munmap
    18
      0.33    0.000003           3         1           execve
    19
      0.22    0.000002           0         3           brk
    20
      0.22    0.000002           2         1           arch_prctl
    21
      0.11    0.000001           0         4           lseek
    22
      0.00    0.000000           0         1           rt_sigprocmask
    23
      0.00    0.000000           0         1           uname
    24
      0.00    0.000000           0         1           getrlimit
    25
      0.00    0.000000           0         2         2 statfs
    26
      0.00    0.000000           0         1           set_tid_address
    27
      0.00    0.000000           0         1           set_robust_list
    28
    ------ ----------- ----------- --------- --------- ----------------
    29
    100.00    0.000911                   356        42 total
  • -d

    显示有关标准错误的strace本身的一些调试输入

  • -f

    跟踪子进程,这些子进程是由于fork(2)系统调用而由当前跟踪的进程创建的

  • -i

    在系统调用时打印指针命令

  • -t

    跟踪的每一行都以时间为前缀

  • -tt

    如果给出两次,则打印时间包含微秒

  • -ttt

    如果给定三次,则打印时间将包括微秒,并且前导部分将打印为自该**以来的秒数

  • -T

    显示花费在系统调用上的时间,这将记录每个系统调用的开始和结束之间的时间差

  • -v

    打印环境,统计信息,temios等调用的未缩写版本,这些结构在调用中非常常见,因此默认行为显示了结构成员的合理子集,使用此选项可获取所有详细信息

  • -V

    显示版本号

  • -e expr

    限度表达式,用于修改要跟踪的事件或如何跟踪他们

  • -e trace=set

    仅跟踪指定的系统调用集,该-c 选项用于确定哪些系统调用可能时跟踪有用的,例如:trace=open,close,read,write表示仅跟踪这四个系统调用

  • -e trace=file

    跟踪所有以文件名作为参数的系统调用

    例如:打印执行ls时跟文件有关的调用

    1
    [root@yangkai ~]# strace -e trace=file ls
    2
    execve("/usr/bin/ls", ["ls"], 0x7fff24a1d180 /* 37 vars */) = 0
    3
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    4
    open("/usr/local/lib/tls/x86_64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    5
    stat("/usr/local/lib/tls/x86_64", 0x7ffeed24d4d0) = -1 ENOENT (No such file or directory)
    6
    open("/usr/local/lib/tls/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    7
    stat("/usr/local/lib/tls", 0x7ffeed24d4d0) = -1 ENOENT (No such file or directory)
    8
    open("/usr/local/lib/x86_64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    9
    stat("/usr/local/lib/x86_64", 0x7ffeed24d4d0) = -1 ENOENT (No such file or directory)
    10
    open("/usr/local/lib/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    11
    stat("/usr/local/lib", {st_mode=S_IFDIR|0755, st_size=248, ...}) = 0
    12
    open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    13
    open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
    14
    open("/usr/local/lib/libcap.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    15
    open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
    16
    open("/usr/local/lib/libacl.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    17
    open("/lib64/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
    18
    open("/usr/local/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    19
    open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    20
    open("/usr/local/lib/libpcre.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    21
    open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
    22
    open("/usr/local/lib/libdl.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    23
    open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
    24
    open("/usr/local/lib/libattr.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    25
    open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
    26
    open("/usr/local/lib/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    27
    open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
    28
    statfs("/sys/fs/selinux", 0x7ffeed24ecc0) = -1 ENOENT (No such file or directory)
    29
    statfs("/selinux", 0x7ffeed24ecc0)      = -1 ENOENT (No such file or directory)
    30
    open("/proc/filesystems", O_RDONLY)     = 3
    31
    stat("/etc/sysconfig/64bit_strstr_via_64bit_strstr_sse2_unaligned", 0x7ffeed24e830) = -1 ENOENT (No such file or directory)
    32
    access("/etc/selinux/config", F_OK)     = 0
    33
    open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
    34
    openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
    35
    open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
    36
    actions-runner-linux-x64-2.263.0.tar.gz  downloads		       github			     response_data_handler.py  vim-8.1.2033		      yhkl-projects
    37
    assignment				 Envs			       go			     snap		       weibo_freshdata.2020-04-10     yunshu_ningxia20200806.DMP
    38
    assignment_yhkl.zip			 extraWork		       p7zip_9.20.1_src_all.tar.bz2  source.ini		       weibo_freshdata.2020-04-10.7z  编写高质量代码_改善Python程序的91个建议.pdf
    39
    db-aggretaion				 foreign-organizations-client  postgis-2.5.1		     test_local_speed.txt      work_dir			      计算的本质:深入剖析程序和计算机_截取版.pdf
    40
    doc					 gdb-8.3.1.tar.gz	       python36			     TurtleDove		       y
    41
    docker-compose.yml			 geoserver-2.16.0	       requirements.txt		     v2ray		       yhkl.pem
    42
    +++ exited with 0 +++
  • -e trace=process

    跟踪涉及过程管理的所有系统调用,对于观察进程的派生,等待和执行步骤很有用

  • -e trace=network

    跟踪所有与网络相关的系统调用

  • -e trace=signal

    跟踪所有信号相关的系统调用

  • -e trace=ipc

    跟踪所有与ipc相关的系统调用

  • -o filename

    将跟踪输出写入导文件中而不是stderr

  • -p pid

    使用进程ID pid附加导该进程并开始跟踪,跟踪可以随时通过键盘中断信号(Ctrl-C)终止

  • -S

    按指定条件对-c选项打印的直方图输出进行排序

    例如:打印执行uname系统调用中calls的次数排序

    1
    [root@yangkai ~]# strace -fc -S calls uname 
    2
    Linux
    3
    % time     seconds  usecs/call     calls    errors syscall
    4
    ------ ----------- ----------- --------- --------- ----------------
    5
     18.58    0.000047           5         9           mmap
    6
     20.55    0.000052           7         7         4 open
    7
      3.95    0.000010           2         5           close
    8
     13.83    0.000035           8         4         3 stat
    9
      3.95    0.000010           2         4           fstat
    10
      6.72    0.000017           4         4           mprotect
    11
      7.51    0.000019           4         4           brk
    12
      5.14    0.000013           6         2           munmap
    13
      1.19    0.000003           3         1           read
    14
      2.37    0.000006           6         1           write
    15
      9.09    0.000023          23         1         1 access
    16
      5.53    0.000014          14         1           execve
    17
      0.79    0.000002           2         1           uname
    18
      0.79    0.000002           2         1           arch_prctl
    19
    ------ ----------- ----------- --------- --------- ----------------
    20
    100.00    0.000253                    45         8 total