0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

说说 linux strace

Last updated at Posted at 2021-05-30

strace 在 linux 下用来跟踪某个进程的系统调用
在 solaris 系统下,对应的是:dtrace。
在 mac 系统下,对应的是:dtruss,ktrace。
另外 pidof 很好用

例子

查看区块链同步的高度的命令 bitcoin-cli -datadir=<dir> getblockcount

strace bitcoin-cli -datadir=<dir> getblockcount
strace bitcoin-cli -datadir=<dir> getblockcount &> out.txt
strace -tt bitcoin-cli -datadir=<dir> getblockcount
# -c 统计每一个系统调用所执行的时间
# 查看请求fb.com的时间花费,poll消耗了97%
strace -c curl fb.com >/dev/null 

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 97.39    0.004000         129        31           poll
  2.61    0.000107           0      2174           write
  0.00    0.000000           0        38           read
  0.00    0.000000           0        39         1 open
  0.00    0.000000           0        41           close
  0.00    0.000000           0        39           fstat
  0.00    0.000000           0       102           mmap
  0.00    0.000000           0        73           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         4           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         1         1 ioctl
  0.00    0.000000           0        37        37 access
  0.00    0.000000           0         1           pipe
  0.00    0.000000           0         1           socket
  0.00    0.000000           0         1           clone
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           fcntl
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           getrusage
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.004107                  2596        39 total
# 跟踪 socket, brk 调用
strace -Txe trace=socket,brk bitcoin-cli -datadir=<dir> getblockcount

brk(NULL)                               = 0x5590e2366000 <0.000004>
brk(NULL)                               = 0x5590e2366000 <0.000005>
brk(0x5590e2387000)                     = 0x5590e2387000 <0.000016>
brk(0x5590e23a8000)                     = 0x5590e23a8000 <0.000009>
socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_IP) = 6 <0.000013>

# 只跟踪epoll_wait调用,使用time记录总时间
time strace -Txe trace=epoll_wait bitcoin-cli -datadir=<dir> getblockcount

epoll_wait(3, [{EPOLLOUT, {u32=6, u64=6}}], 32, 900000) = 1 <0.000006>
epoll_wait(3, [{EPOLLIN, {u32=6, u64=6}}], 32, 900000) = 1 <4.494324>
......
+++ exited with 0 +++

real	0m4.534s
user	0m0.000s
sys	0m0.000s
#跟踪与网络有关的系统调用
strace -Txe trace=network bitcoin-cli -datadir=<dir> getblockcount 

# 跟踪指定的进程pid
strace -Txe trace=network -p `pidof bitcoind`

常用命令

-h 输出简要的帮助信息
-c 统计每一个系统调用所执行的时间,次数和出错次数等
-f 跟踪由fork调用所产生的子进程
-p <pid> 跟踪指定的进程pid
-T 显示每一调用所耗的时间
-u username 以username的UID和GID执行被跟踪的命令
----------------------------------------------------------------------
-e trace=<...> 只跟踪指定的系统调用. 例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为all
-e trace=file 只跟踪有关文件操作的系统调用
-e trace=process 只跟踪有关进程控制的系统调用, 比如fork/exec/exit_group
-e trace=network 跟踪与网络有关的所有系统调用, 比如socket/sendto/connect
-e trace=desc  跟踪文件描述符相关的系统调用, 比如write/read/select/epoll等
-e strace=signal 跟踪所有与系统信号有关的系统调用, 比如kill/sigaction
-e trace=ipc 跟踪所有与进程通讯有关的系统调用, 比如shmget,shmat,shmdt,shmctl
----------------------------------------------------------------------
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出
----------------------------------------------------------------------
-r 打印出关于每一个系统调用的相对时间
-t 在输出中的每一行前加上时间信息
-tt 在输出中的每一行前加上时间信息,微秒级
-ttt 微秒级输出
----------------------------------------------------------------------
-d 输出strace关于标准错误的调试信息
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-i 输出系统调用的入口指针
-q 禁止输出关于脱离的消息

-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.

-a column 设置返回值的输出位置.默认为40
-e expr 指定一个表达式,用来控制如何跟踪.格式:[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.
默认的 qualifier是 trace.感叹号是否定符号.
例如:-eopen等价于 -e trace=open,表示只跟踪open调用.
而-etrace!=open 表示跟踪除了open以外的其他调用.
有两个特殊的符号 all 和 none. 
注意有些shell使用!来执行历史记录里的命令,所以要使用\\

-e abbrev=<...> 设定strace输出的系统调用的结果集.-v 等与abbrev=none.默认为abbrev=all
-e raw=<...> 将指定的系统调用的参数以十六进制显示
-e signal=<...> 指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号
-e read=<...> 输出从指定文件中读出 的数据.例如: -e read=3,5
-e write=<...> 输出写入到指定文件中的数据
-o filename 将strace的输出写入文件filename
-s strsize 指定输出的字符串的最大长度.默认为32.文件名一直全部输出

大家也不妨试试 ltrace,ftrace,sysdig,systemtap,bcc。


参考:
DNS域名解析

学会使用strace诊断问题

使用 dtrace 跟踪 Python 应用
http://www.ruanyifeng.com/blog/2017/09/flame-graph.html
https://cloud.tencent.com/developer/article/1005352
https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/strace.html
https://segmentfault.com/a/1190000010630859
https://nanxiao.me/openat-vs-open
https://suzf.net/post/839
https://www.linuxsong.org/2015/04/mac-os-x-ldd-strace/

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?