Linux:strace的跟踪程序运行过程

strace 用于记录和跟踪程序运行期间收到的信号和调用的系统调用。其中包括跟踪程序运行过程中的向操作系统的内存申请和释放。

一、命令格式

bingsanlang@ubuntu:~$ strace -help
usage: strace [-CdffhiqrtttTvVwxxy] [-I n] [-e expr]...
              [-a column] [-o file] [-s strsize] [-P path]...
              -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]
   or: strace -c[dfw] [-I n] [-e expr]... [-O overhead] [-S sortby]
              -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]

Output format:
  -a column      alignment COLUMN for printing syscall results (default 40) //设置系统调用结果输出的位置,默认为40
  -i             print instruction pointer at time of syscall //系统调用指令的地址
  -o file        send trace output to FILE instead of stderr // 将strace的输出结果写入文件filename,而不是控制台
  -q             suppress messages about attaching, detaching, etc. // 禁止输出关于脱离的消息.
  -r             print relative timestamp // 打印出相对时间戳.
  -s strsize     limit length of print strings to STRSIZE chars (default 32) // 指定输出的字符串的最大长度.默认为32.
  -t             print absolute timestamp // 在输出中的每一行前加上时间信息.
  -tt            print absolute timestamp with usecs // 在输出中的每一行前加上时间信息,微秒级.
  -T             print time spent in each syscall //显示每一调用所耗的时间.
  -x             print non-ascii strings in hex // 以十六进制形式输出非标准字符串
  -xx            print all strings in hex // 所有字符串以十六进制形式输出.
  -y             print paths associated with file descriptor arguments // 打印与文件描述符相关的参数路径
  -yy            print ip:port pairs associated with socket file descriptors // 打印与socket文件描述相关的ip和端口对

Statistics:
  -c             count time, calls, and errors for each syscall and report summary // 统计每一系统调用的所执行的时间,次数和出错的次数等.
  -C             like -c but also print regular output //除了常规统计外,统计每一系统调用的所执行的时间,次数和出错的次数等.
  -O overhead    set overhead for tracing syscalls to OVERHEAD usecs
  -S sortby      sort syscall counts by: time, calls, name, nothing (default time)
  -w             summarise syscall latency (default is system time)

Filtering:
  -e expr        a qualifying expression: option=[!]all or option=[!]val1[,val2]...
     options:    trace, abbrev, verbose, raw, signal, read, write
     //指定一个表达式,用来控制如何跟踪.默认的 qualifier是 trace.感叹号是否定符号.这个下面会重点介绍
  -P path        trace accesses to path

Tracing:
  -b execve      detach on execve syscall
  -D             run tracer process as a detached grandchild, not as parent
  -f             follow forks //跟踪fork出来的进程
  -ff            follow forks with output into separate files // 跟踪fork出来的进程,并放到不同的文件中。
  -I interruptible
     1:          no signals are blocked
     2:          fatal signals are blocked while decoding syscall (default)
     3:          fatal signals are always blocked (default if '-o FILE PROG')
     4:          fatal signals and SIGTSTP (^Z) are always blocked
                 (useful to make 'strace -o FILE PROG' not stop on ^Z)

Startup:
  -E var         remove var from the environment for command
  -E var=val     put var=val in the environment for command
  -p pid         trace process with process id PID, may be repeated //跟踪特定的进程id
  -u username    run command as username handling setuid and/or setgid // 以username 的UID和GID执行被跟踪的命令

Miscellaneous:
  -d             enable debug output to stderr //开启debug日志
  -v             verbose mode: print unabbreviated argv, stat, termios, etc. args
  -h             print help message
  -V             print version

二、示例

写一个demo.c文件:

#include 
int main(void)
{
   
    int i = 10;
    printf("%d\n", i);
    return 0;
}

编译下:

gcc -o demo ./demo.c

先测试下,默认的strace跟踪程序:

2.1 默认strace

bingsanlang@ubuntu:~$ strace ./demo 
execve("./demo", ["./demo"], [/* 72 vars */]) = 0
brk(NULL)                               = 0x1279000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {
   st_mode=S_IFREG|0644, st_size=100479, ...}) = 0
mmap(NULL, 100479, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f00ce5a9000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {
   st_mode=S_IFREG|0755, st_size=1868984, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f00ce5a8000
mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f00cdfd3000
mprotect(0x7f00ce193000, 2097152, PROT_NONE) = 0
mmap(0x7f00ce393000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7f00ce393000
mmap(0x7f00ce399000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f00ce399000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE

你可能感兴趣的:(Linux,问题排查)