如何做测评视频网站,哪个网站能下载gif,德阳建设机械网站,wordpress文章分割strace 是什么
strace 是一个可用于诊断和调试的 Linux 用户空间跟踪器。我们用它来监控用户空间进程和内核的交互#xff0c;比如系统调用、信号传递、进程状态变更等。
strace 作为一种动态跟踪工具#xff0c;能够帮助我们高效地定位进程和服务故障。它像是一个侦探比如系统调用、信号传递、进程状态变更等。
strace 作为一种动态跟踪工具能够帮助我们高效地定位进程和服务故障。它像是一个侦探打开应用进程的这个黑盒子通过系统调用的蛛丝马迹告诉你进程大概在干嘛进而找到异常的真相。
strace 怎么用
运行模式
strace 有两种运行模式。
一种是通过它启动要跟踪的进程。用法很简单在原本的命令前加上 strace 即可。
比如我们要跟踪 “/usr/local/bin/a.out” 这个命令的执行可以这样
strace /usr/local/bin/a.out另外一种运行模式是跟踪已经在运行的进程在不中断进程执行的情况下理解它在干嘛。
这种情况给 strace 传递个 -p pid 选项即可。
比如a.out 进程的 pid 是 345可以这样
strace -p 345完成跟踪时按 Ctrl C 结束 strace 即可。
常用选项
从一个示例命令来看
strace -tt -T -v -f -e tracefile -o /tmp/strace.log -s 1024 -p 345-tt在每行输出的前面显示毫秒级别的时间-T显示每次系统调用所花费的时间-v对于某些相关调用把完整的环境变量文件 stat 结构等打出来-f跟踪目标进程以及目标进程创建的所有子进程-e控制要跟踪的事件和跟踪行为比如指定要跟踪的系统调用名称-o把 strace 的输出单独写到指定的文件-s当系统调用的某个参数是字符串时最多输出指定长度的内容默认是 32 个字节-p指定要跟踪的进程 pid要同时跟踪多个 pid重复多次 -p 选项即可-c统计系统调用的次数和其所花的时间
这里特别说下 strace 的 -e trace 选项。
要跟踪某个具体的系统调用如 -e traceopen 即可。
但有时候我们要跟踪一类系统调用比如所有和文件名有关的调用、所有和内存分配有关的调用。
如果人工输入每一个具体的系统调用名称可能容易遗漏。
于是 strace 提供了几类常用的系统调用组合名字。
-e tracefile 跟踪和文件访问相关的调用(参数中有文件名)-e traceprocess 和进程管理相关的调用比如 fork/exec/exit_group-e tracenetwork 和网络通信相关的调用比如 socket/sendto/connect-e tracesignal 信号发送和处理相关比如 kill/sigaction-e tracedesc 和文件描述符相关比如 write/read/select/epoll-e traceipc 进程间通信相关比如 shmget
strace 问题定位案例
定位进程异常退出
/usr/local/samba/bin/nmbd 启动失败nmbd 是一个域名服务的进程。
这个服务进程是开源代码编译出来的也就是说并不是我们自己开发的代码因此该服务进程的启动流程我们并不熟悉。像这样的情况可以用 strace 来跟踪看看到底是哪里出现了异常。
strace -tt -T /usr/local/samba/bin/nmbd咦看到 nmbd 进程 exited with 0 正常退出了考虑到这个进程是个守护进程主进程确实会 exit 的。
再看到有个 clone 的系统调用想到 fork 这个系统调用最终调用的是 clone就知道 nmbd 进程创建了一个子进程然后父进程就退出了。所以要加一个参数 -f 来跟踪子进程
strace -tt -T -f /usr/local/samba/bin/nmbd看到确实子进程是异常退出了exited with 1所以 nmbd 进程启动失败。
对比了一下之前版本 OK 的启动 log。 发现 /usr/local/samba/var/nmbd 这个目录有异常
OK 时是一个普通的目录
NG 时是一个软链接
最终查看了相关代码改成目录nmbd 进程就可以正常启动了
性能分析
假如有个需求统计某个目录 cpp 文件的代码行数。这里提供两个 Shell 脚本实现
poor_script.sh
#!/bin/bash
total_line0
while read filename; doline$(wc -l $filename | awk {print $1})(( total_line line ))
done (find . -type f -iname *.cpp)
echo total line: $total_linegood_script.sh
#!/bin/bashfind . -type f -iname *.cpp -print0 | wc -l --files0-from- | tail -n 1两段代码实现的目的是一样的。我们通过 strace 的 -c 选项来分别统计两种版本的系统调用情况和其所花的时间使用 -f 同时统计子进程的情况
strace -c -f ./poor_script.sh
strace -c -f ./good_script.sh
从两个输出可以看出good_script.sh 很快就可以得到结果95985 行。它大部分的调用calls开销是文件操作read/open/write/close等统计代码行数本来就是干这些事情。
而 poor_script.sh 完成同样的任务则花了更久的时间。它大部分的调用开销都在进程和内存管理上(wait4/mmap/getpid…)。
实际上从两个图中 clone 系统调用的次数我们可以看出 good_script.sh 只需要启动 3 个进程而 poor_script.sh 完成整个任务居然启动了 392 个进程而进程创建和销毁的代价是相当高的性能不差才怪。如果目录下的 cpp 文件再多一些那要花费的时间将会更久
总结
当发现进程或服务异常时我们可以通过 strace 来跟踪其系统调用“看看它在干啥”进而找到异常的原因。熟悉常用系统调用能够更好地理解和使用 strace。
当然strace 也不是万能的当目标进程卡死在用户态时strace 就没有输出了。
这个时候我们需要其他的跟踪手段比如 gdb 等。