strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统呼叫及它所接收的系统信息。
Strace是一个基础的调试工具,strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。
下载地址:http://sourceforge.net/projects/strace/
[oracle@xml-ora1 ~]$ wgethttp://nchc.dl.sourceforge.net/project/strace/strace/4.7/strace-4.7.tar.xz
这种文件是使用tar打包后再压缩生成的。解压方法是:
1、xz -d **.tar.xz
2、tar -xvf **.tar
如没有按照xz工具,则首先需要下载、安装xz工具:http://tukaani.org/xz/
[oracle@xml-ora1 ~]$ wget http://tukaani.org/xz/xz-5.0.4.tar.gz
[oracle@xml-ora1 ~]$ tar -zxvf xz-5.0.4.tar.gz
[oracle@xml-ora1 ~]$ cd xz-5.0.4
[oracle@xml-ora1 xz-5.0.4]$ ./configure
[oracle@xml-ora1 xz-5.0.4]$ make
[oracle@xml-ora1 xz-5.0.4]$ sudo make install
[oracle@xml-ora1 ~]$ xz --help
Usage: xz [OPTION]... [FILE]...
Compress or decompress FILEs in the .xzformat.
-z,--compress force compression
-d, --decompress force decompression
-t,--test test compressed fileintegrity
-l,--list list information about.xz files
-k,--keep keep (don't delete) inputfiles
-f,--force force overwrite of outputfile and (de)compress links
-c,--stdout write to standard outputand don't delete input files
-0... -9 compression preset;default is 6; take compressor *and*
decompressor memory usageinto account before using 7-9!
-e,--extreme try to improvecompression ratio by using more CPU time;
does not affectdecompressor memory requirements
-q,--quiet suppress warnings;specify twice to suppress errors too
-v,--verbose be verbose; specify twicefor even more verbose
-h,--help display this short helpand exit
-H,--long-help display the long help(lists also the advanced options)
-V,--version display the versionnumber and exit
With no FILE, or when FILE is -, readstandard input.
Report bugs to<[email protected]> (in English or Finnish).
XZ Utils home page:<http://tukaani.org/xz/>
[oracle@xml-ora1 ~]$ xz -d strace-4.7.tar.xz
[oracle@xml-ora1 ~]$ ls
strace-4.7.tar
[oracle@xml-ora1 ~]$ tar -xvf strace-4.7.tar
[oracle@xml-ora1 strace-4.7]$ ./configure
[oracle@xml-ora1 strace-4.7]$ make
[oracle@xml-ora1 strace-4.7]$ sudo make install
[oracle@xml-ora1 strace-4.7]$ strace --help
strace: invalid option -- -
usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-eexpr]...
[-a column] [-o file] [-sstrsize] [-P path]...
-p pid... / [-D] [-E var=val]...[-u username] PROG [ARGS]
or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]
-p pid... / [-D] [-E var=val]...[-u username] PROG [ARGS]
-c -- count time, calls, and errors foreach syscall and report summary统计每一系统调用的所执行的时间,次数和出错的次数等.
-C -- like -c but also print regular output和-c参数意义,但是输出更多信息
-d -- enable debug output to stderr 输出strace关于标准错误的调试信息.
-D -- run tracer process as a detachedgrandchild, not as parent
-f -- follow forks, -ff -- with output intoseparate files 告诉strace同时跟踪fork出来的进程
-F -- attempt to follow vforks (deprecated,use -f) 告诉strace同时跟踪vfork出来的进程
-i -- print instruction pointer at time ofsyscall 输出系统调用的入口指针.
-q -- suppress messages about attaching,detaching, etc. 禁止输出关于脱离的消息
-r -- print relative timestamp, -t --absolute timestamp, -tt -- with usecs 打印出时间,tt表示微妙
-T -- print time spent in each syscall 打印出每个系统调用的耗费时间
-v -- verbose mode: print unabbreviatedargv, stat, termios, etc. args输出strace的版本信息
-x -- print non-ascii strings in hex, -xx-- print all strings in hex以十六进制形式输出非标准字符串
-y -- print paths associated with filedescriptor arguments
-h -- print help message, -V -- printversion输出简要的帮助信息.
-a column -- alignment COLUMN for printingsyscall results (default 40)设置结果的输出默认位置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
跟踪与网络有关的所有系统调用.
-estrace=signal
跟踪所有与系统信号有关的系统调用
-e trace=ipc
跟踪所有与进程通讯有关的系统调用
-eabbrev=set
设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set
将指 定的系统调用的参数以十六进制显示.
-esignal=set
指定跟踪的系统信号.默认为all.如signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.
-e read=set
输出从指定文件中读出的数据.例如:
-e read=3,5
-e write=set
输出写入到指定文件中的数据.
-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)
-o file -- send trace output to FILEinstead of stderr 将strace的输出写入文件filename
-O overhead -- set overhead for tracingsyscalls to OVERHEAD usecs
-p pid -- trace process with process idPID, may be repeated跟踪指定的进程pid.
-s strsize -- limit length of print stringsto STRSIZE chars (default 32) 指定输出的字符串的最大长度.默认为32.文件名一直全部输出
-S sortby -- sort syscall counts by: time,calls, name, nothing (default time)
-u username -- run command as usernamehandling setuid and/or setgid以username 的UID和GID执行被跟踪的命令
-E var=val -- put var=val in theenvironment for command输出变量值
-E var -- remove var from the environmentfor command
-P path -- trace accesses to path
有个文件a.txt,我们跟踪下cat文件的系统调用过程:
[oracle@xml-ora1 ~]$ cat a.txt
hello welcome!
12344
[oracle@xml-ora1 ~]$ strace -o cat.log cat a.txt
hello welcome!
12344
[oracle@xml-ora1 ~]$ cat cat.log
execve("/bin/cat",["cat", "a.txt"], [/* 30 vars */]) = 0
open("/lib/libc.so.6",O_RDONLY) = 3
open("/etc/ld.so.cache",O_RDONLY) = 3
open("/lib64/libc.so.6",O_RDONLY) = 3
open("a.txt", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=21,...}) = 0
read(3, "hellowelcome!\n12344\n", 4096) = 21
write(1, "hellowelcome!\n12344\n", 21) = 21
read(3, "", 4096) = 0
close(3) = 0
close(1) = 0
exit_group(0) = ?
+++ exited with 0 +++
跟踪文件cat.log里一大堆的东西,前面大部分都是在读取系统环境信息以及库文件,最后才是cat调用系统的信息。同时可以看到一个现象,只有是Open=3的,则说明加载库文件成功,而=-1的加载失败。
[oracle@xml-ora1 ~]$ strace -o sqlplus-trace.txtsqlplus / as sysdba
SQL*Plus: Release 10.2.0.4.0 - Productionon Wed Dec 19 15:32:39 2012
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise EditionRelease 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Miningand Real Application Testing options
SQL> exit
[oracle@xml-ora1 ~]$ cat sqlplus-trace.txt | more
加载执行的程序路径,环境变量,系统库信息
execve("/u01/app/oracle/product/10.2/db_1/bin/sqlplus",["sqlplus", "/", "as", "sysdba"], [/*30 vars */]) = 0
brk(0) = 0xe747000
mmap(NULL, 4096, PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae1dec57000
uname({sys="Linux",node="xml-ora1", ...}) = 0
open("/u01/app/oracle/product/10.2/db_1/lib/libsqlplus.so",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/lib/libclntsh.so.10.1",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/lib/libnnz10.so",O_RDONLY) = 3
open("/lib/libdl.so.2",O_RDONLY) = 3
open("/etc/ld.so.cache",O_RDONLY) = 3
open("/lib64/libdl.so.2",O_RDONLY) = 3
open("/lib/libm.so.6",O_RDONLY) = 3
open("/lib64/libm.so.6",O_RDONLY) = 3
open("/lib/libpthread.so.0", O_RDONLY) = 3
open("/lib64/libpthread.so.0",O_RDONLY) = 3
open("/lib/libnsl.so.1",O_RDONLY) = 3
open("/lib64/libnsl.so.1",O_RDONLY) = 3
open("/lib/libc.so.6",O_RDONLY) = 3
open("/lib64/libc.so.6",O_RDONLY) = 3
以下是加载oracle字符集文件
open("/u01/app/oracle/product/10.2/db_1/nls/data/lx1boot.nlb",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/nls/data/lx00001.nlb",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/nls/data/lx20001.nlb",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/nls/data/lx10001.nlb",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/nls/data/lx31040.nlb",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/nls/data/lx40001.nlb",O_RDONLY) = 3
以下加载sqlplus的一些文件,待研究,有些名字很清晰表达了组件的作用
open("/etc/hosts", O_RDONLY) = 8
open("/u01/app/oracle/product/10.2/db_1/sqlplus/mesg/sp1us.msb",O_RDONLY) = 3
open("/u01/app/oracle/product/10.2/db_1/sqlplus/mesg/sp2us.msb",O_RDONLY) = 4
open("/u01/app/oracle/product/10.2/db_1/sqlplus/mesg/cpyus.msb",O_RDONLY) = 5
open("/etc/localtime",O_RDONLY) = 6
open("/u01/app/oracle/product/10.2/db_1/oracore/zoneinfo/timezlrg.dat",O_RDONLY) = 6
输出交互信息到屏幕
write(1, "\n", 1) = 1
write(1, "SQL*Plus: Release 10.2.0.4.0- P"..., 70) = 70
write(1, "\n", 1) = 1
write(1, "Copyright (c) 1982, 2007,Oracle"..., 56) = 56
write(1, "\n", 1) = 1
初始化sqlplus
getcwd("/home/oracle", 256) = 13
access("/u01/app/oracle/product/10.2/db_1/network/admin/sqlnet.ora",F_OK) = 0
open("/u01/app/oracle/product/10.2/db_1/network/admin/sqlnet.ora",O_RDONLY) = 7
open("/etc/passwd",O_RDONLY) = 7
open("/u01/app/oracle/product/10.2/db_1/sqlplus/admin/glogin.sql",O_RDONLY) = 8
write(1, "SQL> ", 5)
这个就是SQLPLUS初始化的过程,当然可以加上-f选项,此时看到的就是更详细的调用了。