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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章