您的位置:首页 > 运维架构 > Linux

linux-系统调用01-strace工具的使用

2015-11-29 15:35 886 查看
1 简介:

strace程序截取程序发出的系统调用并且显示它们以供查看。

2.真实使用实例

在嵌入式串口编程中,有时候某些函数没有集成在所使用的库中。例如tcdrain函数没有集成在某些soc的芯片中。首先在linux系统中编写包含有tcdrain函数的小程序test.c,编译成可执行文件test,使用strace ./test

3 strace的基本使用方法

注: find .|xargs grep -ri “tcdrain” 在当前目录及其子目录搜索“包含有tcdrain字符串的文件”这个命令个工具也是linux系统下搜索字符串的大刀,有时候很有用处–不妨可以记录下,以待后用哦。

root@ubuntu-core:/home# find .|xargs grep -ri “tcdrain”

…..

Binary file ./test/tcdrain matches

./test/tcdrain.c: tcdrain(fd);

…..

root@ubuntu-core:/home/test# cat tcdrain.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

int main()
{
int  fd = open("/dev/ttyS3",O_RDWR);
write(fd,"hello",5);
tcdrain(fd);

return 0;
}


root@ubuntu-core:/home/test#

root@ubuntu-core:/home/test# gcc -o tcdrain tcdrain.c

root@ubuntu-core:/home/test# strace ./tcdrain

execve(“./tcdrain”, [“./tcdrain”], [/* 46 vars */]) = 0 //shell使用execve加载可执行程序

brk(0) = 0xde4000

access(“/etc/ld.so.nohwcap”, F_OK) = -1 ENOENT (No such file or directory)

mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdde8fbd000

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=119536, …}) = 0

mmap(NULL, 119536, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fdde8f9f000

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\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\30\2\0\0\0\0\0”…, 832) = 832

fstat(3, {st_mode=S_IFREG|0755, st_size=1815224, …}) = 0

mmap(NULL, 3929304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fdde89dd000

mprotect(0x7fdde8b92000, 2097152, PROT_NONE) = 0

mmap(0x7fdde8d92000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7fdde8d92000

mmap(0x7fdde8d98000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fdde8d98000

close(3) = 0

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdde8f9e000

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdde8f9d000

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdde8f9c000

arch_prctl(ARCH_SET_FS, 0x7fdde8f9d700) = 0

mprotect(0x7fdde8d92000, 16384, PROT_READ) = 0

mprotect(0x600000, 4096, PROT_READ) = 0

mprotect(0x7fdde8fbf000, 4096, PROT_READ) = 0

munmap(0x7fdde8f9f000, 119536) = 0

open(“/dev/ttyS3”, O_RDWR) = 3

write(3, “hello”, 5) = -1 EIO (Input/output error)

ioctl(3, TCSBRK, 0x1) = 0 //从这里可以看出,tcdrain函数可以使用ioctl替换

exit_group(0) = ?

root@ubuntu-core:/home/test#

4 使用-c参数

在程序执行之后创建一个报告,概述发出的所有系统调用,以及每个系统调用发费的时间,以及调用出错计数。

root@ubuntu-core:/home/test# strace -c ./tcdrain

% time seconds usecs/call calls errors syscall

-nan 0.000000 0 1 read

-nan 0.000000 0 1 1 write

-nan 0.000000 0 3 open

-nan 0.000000 0 2 close

-nan 0.000000 0 2 fstat

-nan 0.000000 0 8 mmap

-nan 0.000000 0 4 mprotect

-nan 0.000000 0 1 munmap

-nan 0.000000 0 1 brk

-nan 0.000000 0 1 ioctl

-nan 0.000000 0 3 3 access

-nan 0.000000 0 1 execve

-nan 0.000000 0 1 arch_prctl

100.00 0.000000 29 4 total

root@ubuntu-core:/home/test#

5 strace的参数

-c

-d 输出strace关于标准错误的调试信息.

-f 跟踪由fork调用所产生的子进程.

root@ubuntu-core:/home/test# strace –help

strace: invalid option – ‘-’

usage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] … [-o file]

[-p pid] … [-s strsize] [-u username] [-E var=val] …

[command [arg …]]

or: strace -c -D [-e expr] … [-O overhead] [-S sortby] [-E var=val] …

[command [arg …]]

-c – count time, calls, and errors for each syscall and report summary

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

-f – follow forks, -ff – with output into separate files

跟踪由fork调用所产生的子进程. -ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.

-F – attempt to follow vforks,

-h – print help message

-i – print instruction pointer at time of syscall

输出系统调用的入口指针

-q – suppress messages about attaching, detaching, etc.

-r – print relative timestamp,-t – absolute timestamp,

-tt – with usecs

-T – print time spent in each syscall, -V – print version

-v – verbose mode: print unabbreviated argv, stat, termio[s], etc. args

-x – print non-ascii strings in hex, -xx – print all strings in hex

-a column – alignment COLUMN for printing syscall results (default 40)

-e expr – a qualifying expression: option=[!]all or option=[!]val1[,val2]…

options: trace, abbrev, verbose, raw, signal, read, or write

指定输出的过滤表达式

-e trace=set

只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系 统调用.默认的为set=all.

-e trace=file

只跟踪有关文件操作的系统调用.

-e trace=process

只跟踪有关进程控制的系统调用.

-e trace=network

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

-e strace=signal

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

-e trace=ipc

跟踪所有与进程通讯有关的系统调用

-e abbrev=set

设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.

-e raw=set

将指 定的系统调用的参数以十六进制显示.

-e signal=set

指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.

-e read=set

输出从指定文件中读出 的数据.例如:

-e read=3,5

-e write=set

输出写入到指定文件中的数据

-o file – send trace output to FILE instead of stderr

-O overhead – set overhead for tracing syscalls to OVERHEAD usecs

-p pid – trace process with process id PID, may be repeated

跟踪指定的进程pid

-D – run tracer process as a detached grandchild, not as parent

-s strsize – limit length of print strings to STRSIZE chars (default 32)

-S sortby – sort syscall counts by: time, calls, name, nothing (default time)

-u username – run command as username handling setuid and/or setgid

-E var=val – put var=val in the environment for command

-E var – remove var from the environment for command

root@ubuntu-core:/home/test#

6.常用方式

<1>.输出信息到文件

root@ubuntu-core:/home/test# strace -o test.txt ./tcdrain

root@ubuntu-core:/home/test# ls test.txt

test.txt**

root@ubuntu-core:/home/test#

<2>.使用-c可以查看到发生错误的系统调用

root@ubuntu-core:/home/test# strace -c ./tcdrain

% time seconds usecs/call calls errors syscall

-nan 0.000000 0 1 read

-nan 0.000000 0 1 1 write

-nan 0.000000 0 3 open

-nan 0.000000 0 2 close

-nan 0.000000 0 2 fstat

-nan 0.000000 0 8 mmap

-nan 0.000000 0 4 mprotect

-nan 0.000000 0 1 munmap

-nan 0.000000 0 1 brk

-nan 0.000000 0 1 ioctl

-nan 0.000000 0 3 3 access

-nan 0.000000 0 1 execve

-nan 0.000000 0 1 arch_prctl

100.00 0.000000 29 4 total

root@ubuntu-core:/home/test#

<3>.挑选查看的系统调用(筛选错误的系统调用,是怎么回事)

root@ubuntu-core:/home/test# strace -e trace=open,write ./tcdrain

open(“/etc/ld.so.cache”, O_RDONLY|O_CLOEXEC) = 3

open(“/lib/x86_64-linux-gnu/libc.so.6”, O_RDONLY|O_CLOEXEC) = 3

open(“/dev/ttyS3”, O_RDWR) = 3

write(3, “hello”, 5) = -1 EIO (Input/output error)

root@ubuntu-core:/home/test#

<4>.附加到正在运行的程序

root@ubuntu-core:/home/test# cat tcdrain.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
int main()
{
int  fd = open("/dev/ttyS3",O_RDWR);
write(fd,"hello",5);
sleep(10);
tcdrain(fd);
return 0;
}


root@ubuntu-core:/home/test#

root@ubuntu-core:/home/test# ./tcdrain &

[1] 2641

root@ubuntu-core:/home/test# strace -p 2641

Process 2641 attached - interrupt to quit

restart_syscall(<… resuming interrupted call …>) = 0

ioctl(3, TCSBRK, 0x1) = 0

exit_group(0) = ?

Process 2641 detached

[1]+ Done ./tcdrain

strace入门,更多的学习,需要man+练习+结合工作只需。see you!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: