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

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

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




# gcc testlsof.c -o testlsof
# ./testlsof &
[1] 3125
# strace -o lsof.strace lsof -p 3125




我们以"/tmp/foo"为关键字搜索输出文档lsof.strace,结果只有一条:



# grep '/tmp/foo' lsof.strace
readlink("/proc/3125/fd/3", "/tmp/foo", 4096) = 8

原来lsof巧妙的利用了/proc/nnnn/fd/目录(nnnn为 pid):Linux内核会为每一个进程在/proc/建立一个以其pid为名的目录用来保存进程的相关信息,而其子目录fd保存的是该进程打开的任何文档的fd。目标离我们很近了。好,我们到/proc/3125/fd/看个究竟:






# cd /proc/3125/fd/
# ls -l
total 0
lrwx------ 1 root root 64 Nov 5 09:50 0 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 5 09:50 1 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 5 09:50 2 -> /dev/pts/0
lr-x------ 1 root root 64 Nov 5 09:50 3 -> /tmp/foo
# readlink /proc/3125/fd/3
/tmp/foo




答案已很明显了:/proc/nnnn/fd/目录下的每一个fd文档都是符号链接,而此链接就指向被该进程打开的一个文档。我们只要用readlink()系统调用就能够获取某个fd对应的文档了,代码如下:



#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
int get_pathname_from_fd(int fd, char pathname[], int n)
{
char buf[1024];
pid_t pid;
bzero(buf, 1024);
pid = getpid();
snprintf(buf, 1024, "/proc/%i/fd/%i", pid, fd);
return readlink(buf, pathname, n);
}
int main(void)
{
int fd;
char pathname[4096];
bzero(pathname, 4096);
fd = open("/tmp/foo", O_CREAT|O_RDONLY);
get_pathname_from_fd(fd, pathname, 4096);
printf("fd=%d; pathname=%s\n", fd, pathname);
return 0;
}




出于安全面的考虑,在FreeBSD 5 之后系统默认已不再自动装载proc文档系统,因此,要想使用truss或strace跟踪程式,您必须手工装载proc文档系统:mount -t procfs proc /proc;或在/etc/fstab中加上一行:



proc                   /proc           procfs  rw              0       0

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