`

Linux 下 strace 命令用法总结

阅读更多

Linux 下 strace 命令用法总结(一)

功能说明


strace 命令是一种强大的工具 能够显示任何由用户空间程式发出的系统调用 strace 显示这些调用的参数并返回符号形式的值 strace 从内核接收信息 而且无需以任何特别的方式来构建内核 strace 的每一行输出包括系统调用名称,   然后是参数和返回值.

下面记录几个常用option :

-f -F选项告诉strace同时跟踪fork和vfork出来的进程

-o xxx.txt 输出到某个文档

-e execve 只记录 execve 这类系统调用 .




详细用法


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

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

              [command [arg ...]]

   or: strace -c [-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

-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

-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

-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




参数说明


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

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

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

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

-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.

-h 输出简要的帮助信息.

-i 输出系统调用的入口指针.

-q 禁止输出关于脱离的消息.

-r 打印出相对时间关于每一个系统调用.

-t 在输出中的每一行前加上时间信息.

-tt 在输出中的每一行前加上时间信息,微秒级.

-ttt 微秒级输出,以秒了表示时间.

-T 显示每一调用所耗的时间.

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

-V 输出strace的版本信息.

-x 以十六进制形式输出非标准字符串 .

-xx 所有字符串以十六进制形式输出.

-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 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 filename   将strace的输出写入文件filename

-p pid   跟踪指定的进程pid.

-s strsize   指定输出的字符串的最大长度.默认为32.文件名一直全部输出.

-u username   以username 的UID和GID执行被跟踪的命令.


--End--

strace -ft -e trace=network -p 29972 -o 29972.log

Linux 下 strace 命令用法总结(二)


strace 调试程序

在理想世界 里, 每当一个程序不能正常执行一个功能时, 它就会给出一个有用的错误提示, 告诉在足够的改正错误的线索. 但遗憾的是, 我们不是生活在理想世界里, 起码不总是生活在理想世界里. 有时候一个程序出现了问题, 无法找到原因. 这就是调试程序出现的原因. strace是一个必不可少的调试工具, strace用来监视系统调用. 不仅可以调试一个新开始的程序, 也可以调试一个已经在运行的程序(把strace绑定到一个已有的PID上 面). 

首先让我们看一个真实的例子: 

启动KDE时出现问题 前一段时间, 我在启动KDE的时候出了问题, KDE 的错误信息无法给我任何有帮助的线索. 


_KDE_IceTransSocketCreateListener: failed to bind listener

_KDE_IceTransSocketUNIXCreateListener: ...SocketCreateListener() failed

_KDE_IceTransMakeAllCOTSServerListeners: failed to create listener for local


Cannot establish any listening sockets DCOPServer self-test failed.


对我来说这个 错误信息没有太多意义, 只是一个对KDE 来说至关重要的负责进程间通信的程序无法启动. 我还可以知道这个错误和ICE协议(Inter Client Exchange)有关, 除此之外, 我不知道什么是KDE启动出错的原因. 我决定采用strace看一下在启动 dcopserver时到底程序做了什么: 


strace -f -F -o ~/dcop-strace.txt dcopserver


这里 -f -F选项告诉strace同时跟踪fork 和vfork出来的进程, -o选项把所有strace输出写到~/dcop-strace.txt里 面, dcopserver是要启动和调试的程序. 再次出现错误之后, 我检查了错误输出文件dcop-strace.txt, 文件里有很多系统调用的记录. 在程序运行出错前的有关记录如下: 


其中第一行显 示程序试图创建/tmp/.ICE- unix目录, 权限为0777, 这个操作因为目录已经存在而失败了. 第二个系统调用(lstat64)检查了目录状态, 并显示这个目录的权限是 0755, 这里出现了第一个程序运行错误的线索: 程序试图创建属性为0777的目录, 但是已经存在了一个属性为 0755的目录. 第三个系统调用 (unlink)试图删除一个文件, 但是这个文件并不存在. 这并不奇怪, 因为这个操作只是试图删掉可能存在的老文件. 

但是, 第四 行确认了错误所在. 它试图绑定到/tmp /.ICE-unix/dcop27207-1066844596, 但是出现了拒绝访问错误. ICE_unix目录的用户和组都是root, 并且只有所有者具有写权限. 一个非root用户无法在这个目录下面建立文件, 如果把目录属性改成0777,  则前面的操作有可能可以执行, 而这正是第一步错误出现时进行过的操作. 

所以我运行了chmod 0777 /tmp /.ICE-unix之后KDE就可以正常启动了, 问题解决了, 用strace进行跟踪调试只需要花很短的几分钟时间跟踪程序运行, 然后检查并分析输出文件. 

说明: 运行 chmod 0777只是一个测试, 一般不要把一个目录设置成所有用户可读写, 同时不设置粘滞位(sticky bit). 给目录设置粘滞位可以阻止一个用户随意删除可写目录下面其它人的文件. 一般会发现/tmp目录因为这个原因设置了粘滞位. KDE可以正常启动之后, 运行chmod +t /tmp/.ICE-unix 给.ICE_unix设置粘滞位.




strace 解决库依赖问题


starce 的另一个用处是解决和动态库相关的问题. 当对一个可执行文件运行ldd 时, 它会告诉程序使用的动态库和找到动态库的位置. 但是如果正在使用一个比较老的glibc版本(2.2或更早), 可能会有一个有bug的ldd程序, 它可能会报告在一个目录下发现一个动态库, 但是真正运行程序时动态连接程序 (/lib/ld-linux.so.2)却可能到另外一个目录去找动态连接库. 这通常因为/etc/ld.so.conf和 /etc/ld.so.cache文件不一致, 或者/etc/ld.so.cache被破坏. 在glibc 2.3.2版本上这个错误不会出现, 可能ld-linux的这个bug已经被解决了. 

尽管这 样, ldd并不能把所有程序依赖的动态库列出来, 系统调用dlopen可以在需要的时候自动调入需要的动态库, 而这些库可能不会被ldd列出来. 作为glibc的一部分的 NSS(Name Server Switch)库就是一个典型的例子, NSS的一个作用就是告诉应用程序到哪里去寻找系统帐号数据库. 应用程序不会直接连接到NSS库, glibc则会通 过dlopen自动调入NSS库. 如果这样的库偶然丢失, 不会被告知存在库依赖问题, 但这样的程序就无法通过用户名解析得到用户ID了. 

让我 们看一个例子: 

whoami程序会给出自己的用户名, 这个程序在一些需要知道运行程序的真正用户的脚本程序里面非常有用, whoami的一个示 例输出如下:  


27207 mkdir("/tmp/.ICE-unix", 0777) = -1 EEXIST (File exists)

27207
  lstat64("/tmp/.ICE-unix", {st_mode=S_IFDIR|S_ISVTX|0755, st_size=4096, ...}) = 0
27207 unlink("/tmp/.ICE-unix/dcop27207-1066844596") = -1 ENOENT (No such file or directory)

27207 bind(3, {sin_family=AF_UNIX, path="/tmp/.ICE-unix/dcop27207-1066844596"}, 38) = -1 EACCES (Permission denied)

27207 write(2, "_KDE_IceTrans", 13) = 13

27207 write(2, "SocketCreateListener: failed to "..., 46) = 46

27207 close(3) = 0 27207 write(2, "_KDE_IceTrans", 13) = 13

27207 write(2, "SocketUNIXCreateListener: ...Soc"..., 59) = 59

27207 umask(0) = 0 27207 write(2, "_KDE_IceTrans", 13) = 13

27207 write(2, "MakeAllCOTSServerListeners: fail"..., 64) = 64

27207 write(2, "Cannot establish any listening s"..., 39) = 39


假设因为某种原因在升级 glibc的过程中负责用户名和用户ID转换的库NSS丢失, 我们可以通过把nss库改名来模拟这个环境:  


# whoami

root


这里可以看到, 运行whoami时出现了错误, ldd程序的输出不会提供有用的帮助:  


只会看到whoami依赖Libc.so.6和ld-linux.so.2, 它没有给出运行 whoami所必须的其它库. 这里时用strace跟踪 whoami时的输出:  


# mv /lib/libnss_files.so.2 /lib/libnss_files.so.2.backup

# whoami

whoami: cannot find username for UID 0


可以发现在不同目录下面查找libnss.so.2的尝试, 但是都失败了. 如果没有strace这样的工具, 很难发现这个错误是由于缺少动态库造成的. 现在只需要找到libnss.so.2并把它放回到正确的位置就可以了.




限制strace 只跟踪特定的系统调用


如果已经知道要找什么, 可以让strace只跟踪一些类型的系统调用. 例如, 需要看看在configure脚本里面执行的程序, 需要监视的系统调用就是execve. 让strace只记录execve的调用用这个命令:  


# ldd /usr/bin/whoami

libc.so.6 => /lib/libc.so.6 (0x4001f000)

/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)


部分输出结果为:  


已经看到 了, strace不仅可以被程序员使用, 普通系统管理员和用户也可以使用strace来调试系统错误. 必须承认, strace的输出不总是容易理解, 但是很多输出对大多数人来说是不重要的. 会慢慢学会从大量输出中找到可能需要的信息, 像权限错误, 文件未找到之类的, 那时strace就会成为一个有力的工具了. 


分享到:
评论

相关推荐

    linux的strace命令(详解)

    Linux 的 Strace 命令详解 Strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用。Strace 显示这些调用的参数并返回符号形式的值。Strace 从内核接收信息,而且不需要以任何特殊的方式来构建...

    linux的strace命令.docx

    `strace`是Linux系统中一个强大的调试和故障排除工具,用于追踪和显示进程执行时的系统调用和信号。它可以帮助开发者和系统管理员理解程序在操作系统级别是如何工作的,尤其是在遇到程序崩溃、性能问题或者奇怪的...

    strace 命令用法

    ### 一、strace命令的基本结构 `strace`命令的基本格式如下: ```bash strace [选项] [-e trace=EXPR] [-f] [-tt] [-T] [-p PID] [-PPID] [-c] [-o FILE] [-s SIZE] [--seccomp] [command [args...]] ``` 其中,`...

    Linux应用调试之strace命令详解

    5. 将编译好的strace命令复制到可执行路径,如 `/bin` 目录下。 ### 3. strace命令使用 strace提供多种选项以满足不同需求,常见的有: - `-o file`:指定跟踪信息的输出文件,如 `strace -o log.txt` 将输出...

    嵌入式linux下移植strace调试应用程序工具源码

    这篇内容将详细介绍如何在嵌入式Linux环境下移植并使用`strace`调试工具。 首先,我们要理解`strace`的工作原理。`strace`通过拦截和记录进程的系统调用来运行,它可以显示调用的系统函数、参数、返回值等信息,这...

    strace跟踪工具使用手册

    Strace是一个在Linux环境下用于诊断、调试和跟踪系统调用和进程间通信的工具。它通过跟踪和记录指定进程对内核的调用和接收的信号,将系统调用的名字、参数、返回值打印出来,这对于解决和定位问题非常有帮助。 在...

    linux下的程序调试工具ltrace和strace终版.pdf

    Linux下的程序调试工具ltrace和strace终版 在 Linux 操作系统中,程序调试是非常重要的一步,对于程序的开发、测试和优化都起着至关重要的作用。在 Linux 中,有两种常用的程序调试工具:ltrace 和 strace。这两种...

    strace命令 跟踪系统调用

    strace命令是一个集诊断、调试、统计与一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。 strace常用来跟踪进程执行时的系统...

    linux调度启动命令.rar

    5. `/sys` 文件系统:在 `/sys/fs/cgroup` 目录下,你可以找到控制组(cgroups)的相关配置,这是一套限制、记录和隔离进程资源的机制,包括CPU使用率。 6. `sysctl`:这个命令用于查看和调整内核参数,包括与调度...

    Linux性能调优命令精华

    "Linux性能调优命令精华"这个主题涵盖了在优化Linux系统性能时常用的命令,这些命令可以帮助我们监控系统状态、诊断问题,并进行必要的调整。 首先,`top`和`htop`命令是实时查看系统资源使用情况的基本工具。`top`...

    strace-4.5.

    例如,要跟踪ls命令的所有系统调用,可以使用`strace ls`。 2. 选择跟踪的系统调用:使用`-e`选项指定要跟踪的系统调用,如`strace -e trace=open,write ls`只跟踪open和write两个系统调用。 3. 控制输出信息:...

    Linux常用命令-API手册.zip

    "Linux常用命令大全.chm"则可能包含更为全面的命令集,不仅包含基础命令,还可能涉及高级用法和一些不那么常用的工具。例如: 7. 脚本编程:`bash`基础知识,包括变量、条件语句、循环结构,以及函数的编写。 8. ...

    strace-4.5.15.tar.bz2.rar

    总结,strace作为Linux系统中的一个重要工具,其强大的系统调用追踪能力对于开发者和系统管理员来说是不可或缺的。通过对"strace-4.5.15.tar(1)"的安装和使用,不仅可以学习strace的基本操作,更能深入理解系统调用...

    linux命令之调试工具strace的深入分析

    最后,strace的电子书《linux的strace命令(详解).txt》可以在新浪电子书平台上下载,对于希望深入了解strace的用户来说,是一个非常好的学习资源。而man strace则提供了Linux系统中strace的官方手册页,用户可以通过...

    linux下的rs232测试程序

    总结,"linux下的rs232测试程序"是一个帮助开发者和系统管理员在Linux环境中测试和使用串口通信的工具。通过理解串口通信的基本原理,配置串口参数,以及学习如何在Linux中进行串口编程,用户能够有效地利用这个程序...

    150个常用Linux命令

    通过以上命令的学习和实践,不仅可以提升你在Linux系统下的工作效率,还可以帮助你更好地理解Linux的工作原理。记住,命令的掌握需要不断练习和使用,理论结合实践才能真正掌握。希望每位学习者都能通过这些基础知识...

    Linux教程-使用truss、strace或ltrace诊断软件

    在Linux系统中,当遇到软件运行异常,如进程无法启动、性能下降或出现"Segment Fault"等错误时,开发者和系统管理员通常会借助于一些强大的调试工具来定位问题。truss、strace和ltrace是三个非常实用的系统级调试...

    基于Linux调试工具strace与gdb的常用命令总结

    strace和gdb是Linux环境下的两个常用调试工具,这里是个人在使用过程中对这两个工具常用参数的总结,留作日后查看使用。strace调试工具strace工具用于跟踪进程执行时的系统调用和所接收的信号,包括参数、返回值、...

Global site tag (gtag.js) - Google Analytics