手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

使用truss、strace或ltrace诊断软件的

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!




我们用truss跟踪clint的系统调用执行情况,并把结果输出到文档clint.truss,然后用tail查看最后几行。注意看clint执行的最后一条系统调用(倒数第五行):stat("/root/.clint/plugins",0xbfbfe680) ERR#2 'No such file or directory',问题就出在这里:clint很难找到目录"/root/.clint/plugins",从而引发了段错误。怎样解决?很简单: mkdir -p /root/.clint/plugins,但是这次运行clint还是会"Segmentation Fault"9。继续用truss跟踪,发现clint还需要这个目录"/root/.clint/plugins/python",建好这个目录后 clint终于能够正常运行了。

案例二:vim启动速度明显变慢



操作系统:FreeBSD-5.2.1-release


vim版本为6.2.154,从命令行运行vim后,要等待近半分钟才能进入编辑界面,而且没有任何错误输出。仔细检查了. vimrc和任何的vim脚本都没有错误配置,在网上也很难找到类似问题的解决办法,难不成要hacking source code?没有必要,用truss就能找到问题所在:



# truss -f -D -o vim.truss vim




这里-D参数的作用是:在每行输出前加上相对时间戳,即每执行一条系统调用所耗费的时间。我们只要关注哪些系统调用耗费的时间比较长就能够了,用less仔细查看输出文档vim.truss,很快就找到了疑点:



735: 0.000021511 socket(0x2,0x1,0x0)       = 4 (0x4)
735: 0.000014248 setsockopt(0x4,0x6,0x1,0xbfbfe3c8,0x4) = 0 (0x0)
735: 0.000013688 setsockopt(0x4,0xffff,0x8,0xbfbfe2ec,0x4) = 0 (0x0)
735: 0.000203657 connect(0x4,{ AF_INET 10.57.18.27:6000 },16) ERR#61 'Connection refused'
735: 0.000017042 close(4) = 0 (0x0)
735: 1.009366553 nanosleep(0xbfbfe468,0xbfbfe460) = 0 (0x0)
735: 0.000019556 socket(0x2,0x1,0x0) = 4 (0x4)
735: 0.000013409 setsockopt(0x4,0x6,0x1,0xbfbfe3c8,0x4) = 0 (0x0)
735: 0.000013130 setsockopt(0x4,0xffff,0x8,0xbfbfe2ec,0x4) = 0 (0x0)
735: 0.000272102 connect(0x4,{ AF_INET 10.57.18.27:6000 },16) ERR#61 'Connection refused'
735: 0.000015924 close(4) = 0 (0x0)
735: 1.009338338 nanosleep(0xbfbfe468,0xbfbfe460) = 0 (0x0)


vim试图连接10.57.18.27这台主机的6000端口(第四行的 connect()),连接失败后,睡眠一秒钟继续重试(第6行的nanosleep())。以上片断循环出现了十几次,每次都要耗费一秒多钟的时间,这就是vim明显变慢的原因。可是,您肯定会纳闷:"vim怎么会无缘无故连接其他电脑的6000端口呢?"。问得好,那么请您回想一下6000是什么服务的端口?没错,就是X Server。看来vim是要把输出定向到一个远程X Server,那么Shell中肯定定义了DISPLAY变量,查看.cshrc,果然有这么一行:setenv DISPLAY $:0,把他注释掉,再重新登录,问题就解决了。



案例三:用调试工具掌控软件的工作原理



操作系统:Red Hat Linux 9.0



用调试工具实时跟踪软件的运行情况不但是诊断软件"疑难杂症"的有效的手段,也可帮助我们理清软件的"脉络",即快速掌控软件的运行流程和工作原理,不失为一种学习源代码的辅助方法。下面这个案例展现了如何使用strace通过跟踪别的软件来"触发灵感",从而解决软件研发中的难题的。



大家都知道,在进程内打开一个文档,都有唯一一个文档描述符(fd:file descriptor)和这个文档对应。而本人在研发一个软件过程中碰到这样一个问题:已知一个fd ,如何获取这个fd所对应文档的完整路径?不管是Linux、FreeBSD或是其他Unix系统都没有提供这样的API,怎么办呢?我们换个角度思考: Unix下有没有什么软件能够获取进程打开了哪些文档?假如您经验足够丰富,很容易想到lsof,使用他既能够知道进程打开了哪些文档,也能够了解一个文档被哪个进程打开。好,我们用一个小程式来试验一下lsof,看他是如何获取进程打开了哪些文档。



/* testlsof.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
open("/tmp/foo", O_CREAT|O_RDONLY); /* 打开文档/tmp/foo */
sleep(1200); /* 睡眠1200秒,以便进行后续操作 */
return 0;
}




将testlsof放入后台运行,其pid为3125。命令lsof -p 3125查看进程3125打开了哪些文档,我们用strace跟踪lsof的运行,输出结果保存在lsof.strace中:

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!