1. dtrace 跟踪用户程序中的函数如printf。
#include
void hello(char * a,int i)
{
printf("%s\n",a);
}
void main()
{
while(1)
{
hello("1",2);
sleep(1);
}
}
将程序编译成a.out并运行。然后运行dtrace -qn 'printf:entry { printf("%s:%s:%s:%s\n",probeprov,probemod,probefunc,probename);}'
并没有任何输出结果。
但是将脚本改为dtrace -qn 'pid1123::printf:entry { printf("%s:%s:%s:%s\n",probeprov,probemod,probefunc,probename);}' 后此处
1123是a.out的进程号。然后就可以输出了。中途改脚本,继续运行上面的脚本还会继续跟踪1123进程。但是不知道什么时候fbt
genunix printf entry会生效。
2. dtrace 跟踪结构体
b.h头文件。
#pragma pack(1)
struct a{
int i;
char *a;
short j;
char b[10];
};
//b.c主程序。
#include
#include"b.h"
#include
void hello(struct a *p)
{
printf("%d\t%d\n",p,&p);
sleep(1);
}
void main()
{
struct a b;
while(1){
b.i=10;
strcpy(b.b,"wanjm");
b.j=11;
hello(&b);
}
}
//b.d脚本
#pragma D option quiet
#include "b.h"
struct a *p; /*只能在外面生命变量.另外包含头文件需要用-I参数指明头文件的路径.还需要-C,以c processor进行预处理.*/
pid$1::hello:entry{
//由于dtrace工作于内核空间,为了访问用户态数据,必须先进行拷贝,才可以访问.
p=copyin(arg0,sizeof(struct a));
printf("%s\n",p->b);
}
dtrace -s scriptname。
3.关于dtrace中函数名参数的初步认识。arg0~9是对应该函数的9的参数,但是该参数都是二进制的,表示数值或地址。所以需要求得该变量的
内容需要将其作为地址,并将其中的内容拷贝到内核中才可以看到。如果该参数正好是数值,则没有必要这么做了,对浮点数还没有把握。
4.dtrace中有一个内置变量fds,是一个数组,以文件描述符为索引,可以得到该描述符所指的文件信息。
#!/usr/sbin/dtrace -qs
syscall::write*:entry
/fds[arg0].fi_pathname==$1/
{
printf("uid:%d %s %s\n",uid,execname,fds[arg0].fi_pathname);
}
此处的$1是文件的全路径. 如果路径中有链接,需要恢复. 如写文件/omp-data/log.txt. 由于/omp-data-> /omp/omp-data.所以实际$1还是等
于/omp/omp-data/log.txt
详细可以搜索dtrace fds
5. dtrace跟踪一个进程打开了哪些文件?
dtrace -n 'open:entry/pid==945/{printf("%d opend %s\n",pid,copyinstr(arg0));}'
阅读(1481) | 评论(0) | 转发(0) |