Vastiny

May 08, 2021

查阅系统调用 strace 和 instruments

Strace 相关

Linux

背景:

在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。

strace 常用来跟踪进程执行时的系统调用和所接收的信号,当然strace对于代码里的死循环是解决不了的。比如你发现一个进程 CPU 100% 了,strace 恐怕是解决不了的。因为 strace 是看系统调用,一般都是 IO 类操作,既然是 IO 密集,那 CPU 一定不可能是100%。

语法:

  • strace -f -F command
    • 比如 strace php abc.php
    • 比如 strace node abc.js
    • -f -F 同事跟踪 fork 和 vfork 出来的进程
  • strace -o output.txt -T -tt -e trace=all -p process-pid
    • -e trace=all 跟踪 pid 所有的系统调用
    • -T 统计系统调用花费的时间
    • -tt 开始时间(更多选项看 man strace)

例子:

uptime 会读取 /proc/uptime/proc/loadavg 获取详细信息,怎么去判断的呢?

1
2
3
4
5
$ strace uptime 2>&1 | grep open
...
open("/proc/uptime", O_RDONLY) = 3
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 4
open("/proc/loadavg", O_RDONLY) = 4

也可以使用strace -e open uptime 获得更加简便的,也可以通过 strace -e trace=file -f uptime获取结果相对复杂。

macOS

macOS 也有类似

背景

  • dtruss [-acdeflhoLs] [-t syscall] { -p PID | -n name | command }

安全问题:sudo dtruss [dtruss_options] -f sudo -u $USER myprogram [program_options]

  • iosnoop: snoop I/O events as they occur. Uses DTrace.
  • opensnoop, execsnoop, 这个可以找到使用 dtrace 相关的都不能用man -k dtrace
    这些都是关于对应的系统调用,但都需要关闭系统保护,不然直接诶调用 dtrace 就会出现下面的内容:
1
2
3
4
5
6
7
dtrace: error on enabled probe ID 1712 (ID 564: syscall::sysctl:return): invalid user access in action #5 at DIF offset 0
dtrace: error on enabled probe ID 1712 (ID 564: syscall::sysctl:return): invalid user access in action #5 at DIF offset 0
dtrace: error on enabled probe ID 1930 (ID 832: syscall::proc_info:return): invalid user access in action #5 at DIF offset 0
dtrace: error on enabled probe ID 1930 (ID 832: syscall::proc_info:return): invalid user access in action #5 at DIF offset 0
dtrace: error on enabled probe ID 1712 (ID 564: syscall::sysctl:return): invalid user access in action #5 at DIF offset 0
dtrace: error on enabled probe ID 1712 (ID 564: syscall::sysctl:return): invalid user access in action #5 at DIF offset 0
dtrace: error on enabled probe ID 1930 (ID 832: syscall::proc_info:return): invalid user access in action #5 at DIF offset 0

所以使用 XCode 提供的 instruments 才是更好的方案:

instruments 语法

  • instruments [-w device] [-t template] [-D document] [-l timeLimit] [-i #] [[-p pid] | [application [-e variable value] [argument …]]]

instruments 例子:

使用 instruments 来查看调用:

  • instruments -D result.trace -t ‘System Trace’ /usr/bin/uptime
  • open result.trace

就可以看到对应的底层调用

关于 xctrace

这个是用来替换 instruments 的,用法先看看 man xctrace 吧,功能跟 instruments 类似。

strace、dtrace 和 dtruss 的介绍

  • strace(Linux) - trace system calls and signals
  • dtrace(macOS) - dynamic tracing compiler and tracing utility
  • dtruss(macOS) - process syscall details. Uses DTrace.

Ref

OLDER > < NEWER