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

发布了24 篇原创文章 · 获赞 26 · 访问量 12万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章