systemtap双指针(多级指针)解引用

刚学systemtap不久,没有找到双指针或者多级指针的解引用api,只好自己实现一个了。

#include <stdio.h>

struct test {
    char *a;
    int b;
};

static void func(const char *pstr, const char **ppstr, struct test *pt, struct test **ppt, struct test ***pppt)
{
    printf("pstr: %s, *ppstr: %s\n", pstr, *ppstr);
    printf("pt->a: %s, pt->b: %d: \n", pt->a, pt->b);
    printf("(*ppt)->a: %s, (*ppt)->b: %d: \n", (*ppt)->a, (*ppt)->b);
    printf("(**pppt)->a: %s, (**pppt)->b: %d: \n", (**pppt)->a, (**pppt)->b);
}

int main(int argc, char *argv[])
{
    const char *pstr = "Hello World!";
    struct test t = {
        .a = "aabbcc",
        .b = 11
    };
    struct test *pt = &t;
    struct test **ppt = &pt;

    func(pstr, &pstr, pt, ppt, &ppt);

    return 0;
}

文件名为cc_deref.c

编译:gcc -Wall -g -o cc_deref ./cc_deref.c

下面是cc_deref.stp脚本:

function deref:long(ptr:long)
%{
    STAP_RETURN(*(void **)STAP_ARG_ptr); 
%}

probe process("cc_deref").statement("func@./cc_deref.c:10")
{
    printf("-------------------------------------------------------------\n");
    printf("$$vars: %s\n", $$vars);
    printf("$pstr: %p, user_string($pstr): %s\n", $pstr, user_string($pstr));
    printf("$ppstr: %p, user_string($ppstr): %s, user_string(deref($ppstr)): %s\n", $ppstr, user_string($ppstr), user_string(deref($ppstr)));

    pt1 = $pt;
    pt2 = deref($ppt);
    pt3 = deref(deref($pppt));

    printf("pt1: %p, pt2: %p, pt3: %p\n", pt1, pt2, pt3);
    printf("$pt=>a: %s, $pt->a: %s, $pt->b: %d\n", user_string(@cast($pt, "struct test")->a), user_string($pt->a), $pt->b);
    printf("pt1=>a: %s, pt1->b: %d\n", user_string(@cast(pt1, "struct test")->a), pt1->b);
    printf("$ppt=>a: %s, $ppt->a: %s, $ppt->b: %d\n", user_string(@cast($ppt, "struct test")->a), user_string($ppt->a), $ppt->b);
    printf("pt2=>a: %s, pt2->b: %d\n", user_string(@cast(pt2, "struct test")->a), @cast(pt2, "struct test")->b);
    printf("$pppt=>a: %s, $pppt->a: %s, $pppt->b: %d\n", user_string(@cast($pppt, "struct test")->a), user_string($pppt->a), $pppt->b);
    printf("pt3=>a: %s, pt3->b: %d\n", user_string(@cast(pt3, "struct test")->a), @cast(pt3, "struct test")->b);

    printf("-------------------------------------------------------------\n");

    exit();
}
其实主要是嵌入C代码来达到解引用的目的,函数deref就一行代码,不过返回的是void *指针,需要用@cast来转换成你需要的类型。

运行:stap -gu -c ./cc_deref cc_deref.stp   注意别漏了-gu参数,这个参数是嵌入C代码必须的参数。


pt1为$pt,是一维指针,$ppt是二维指针,解引用后得到一维指针pt2,$pppt是三维指针,经过两次解引用后得到一维指针pt3,从运行结果可以看出pt1,pt2,pt3的值是一样的,用@cast转换指针后再用user_string读取a的内容也一样,结合cc_deref.c代码符合预期。

但,cc_deref.stp第18、20、22行直接user_string($pt->a)、user_string($ppt->a)、user_string($pppt->a)都能直接得到a的内容,这个就有点不好理解了,如果哪位大神知道,希望不吝赐教。

systemtap文章参考:

http://blog.csdn.net/justlinux2010/article/details/17653601

http://blog.csdn.net/linyt/article/category/645022

http://csrd.aliapp.com/?tag=systemtap

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值