1 Star2 Stars3 Stars4 Stars5 Stars (还没有评分)
Loading...

DTrace tricks and tips (15) -通过二级指针访问内存的值

由于DTrace probe在操作系统的kernel空间执行,所以不能直接访问进程user space的内容。通常要使用copyincopyinstr这些函数把进程user space的内容copy出来。如果程序里的变量是个二级指针,就要相对麻烦一些。以下面程序为例(编译成32位的程序,所以指针用uint32_t):

#include <stdio.h>
void func(char **p)
{
        *p = strdup("hello");
        return;
}
int main(void)
{
        char *p = NULL;
        func(&p);
        printf("%s\n", p);
        return 0;
}

如果要在func函数返回时,打印p指针指向的字符串值。可以使用以下脚本:

#!/usr/sbin/dtrace -qs

pid$target::func:entry
{
        self->s = arg0;
}

pid$target::func:return
{
        this->s = (uint32_t*)copyin(self->s, sizeof(uint32_t));
        printf("%s\n",copyinstr(*(this->s)));
}

首先,在pid$target::func:entry这个probe里,记录下p的值。
接下来,在pid$target::func:return这个probe里,第一次copyin操作把*p的值copythis->s所指向的kernel内存里,*(this->s)则为*p的值,由于这个值所指向的地址依然是user space的地址,所以要打印这个字符串,还要用一次copyinstr

执行脚本,运行结果如下:

-bash-3.2# ./debug.d -c ./a
hello
hello

可以看到一个“hello”是程序打印出来的,另一个是脚本打印出来的。

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.