SystemTap 常用變數 巨集 函式和技巧

2021-08-02 20:22:39 字數 3916 閱讀 2496

後面會持續更新,方便自己,方便大家.......

一、巨集

1. kderef

從指定的位址處讀取指定大小的值

格式為:

kderef(size, address);

其中address為要讀取的位址值,size是要是讀取的值的大小,返回值就是所讀取的值。

2.kread

在嵌入的c**中安全地讀取指標值

格式為:

kread(

&(address))

二、函式 1.

execname()

獲取當前程序的名稱,即可執行檔案的名稱

2. pid()

獲取當前程序的pid

3.pp()

獲取當前的probe點。例如 probe process.syscall,process.end ,在塊中呼叫pp()可能會返回"process.syscall"和"process.end"。

4.probefunc()

獲取當前probe的函式名稱。例如probe sys_read函式,在probe塊中呼叫該函式就會返回sys_read。注意這個函式的返回值是從pp()返回的字串中解析得到的。

5.tid()

獲取當前執行緒的id

6.cpu()

獲取當前cpu的id

7.gettimeofday_s()

獲取當前unix時間

8.get_cycles()

獲取處理器週期數

9.ppfunc()

獲取當前probe的函式名稱。在probe指定檔案中的函式中時非常有用,可以知道當前的probe位於哪個函式。

10.print_backtrace()

列印核心呼叫棧資訊

11.print_ubacktrace()

列印使用者態呼叫棧資訊

12.thread_indent()

輸出當前執行緒的資訊,格式為「相對時間 程式名稱(執行緒id):(空格)」,如果當前probe的函式執行的次數約到,空格的數量也就越多。這個函式還有乙個引數,用來控制空格的數量。如果引數值越大,則空格的數量越多。相對時間是當前的時間(以微秒為單位)減去指定執行緒第一次執行thread_indent時的時間。

13.target()

獲取當前指令碼針對的目標程序id。需要配置stap的-c或-x命令使用。

三、技巧

1.@cast()操作

如果將乙個獲取的值(可能是乙個型別的位址值)儲存到systemtap中定義的變數,但是在讀取的時候需要根據特定的型別去讀取,此時,可以使用@cast()操作來讀取。

其格式為

@cast(p, 

"type_name"[,

"module"])

->member

在systemtap中使用cast來將指定的位址值轉換為c語言中的型別,並且可以去獲取相應的值(例如結構體成員)示例如下

function is_tcp_packet

:long(iphdr) ) 

/* <-- expression */ }

如果是在probe內,還可以直接使用$ptr來獲取成員的值,例如:

probe begin

probe kernel.function(

"tcp_v4_rcv")

@cast()操作中還可以指定型別所在的標頭檔案,示例如下:

@cast(tv, 

"timeval", 

"")-

>tv_sec

@cast(task, 

"task_struct", 

"kernel")

->tgid

2.在使用嵌入c**作為函式體的輔助函式中獲取引數和設定返回值

如果版本是1.8或更新的,則使用stap_arg_(引數名)來獲取引數,例如stap_arg_arg,其中arg是引數名。設定返回值的形式是stap_retvalue=value。

如果版本是1.7或更老的,則使用this->(引數名)來獲取引數,例如this->arg,其中arg是引數名。設定返回值的形式是this->__retvalue=value。

3.獲取probe函式的引數

如果帶debuginfo,即dwarf probes,則可以直接使用引數的名稱加'$'即可,例如sys_read()中的第乙個引數fd,就可以通過$fd來獲取其值。

如果缺少debuginfo,即

dwarf-less probing,則需要通過uint_arg(),pointer_arg()和ulong_arg()等來獲取,這些函式都需要指定當前要獲取的引數是第幾個引數,編號從1開始。例如

asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t 

count)中,uint_arg(1)獲取的是fd的值,pointer_arg(2)獲取的是buf的位址值,ulong_arg(3)獲取的是count引數。更多的獲取引數的函式參見man page index。

如果是通過process.syscall、process("path").syscall或者process(pid).syscall來probe系統呼叫,則可以通過$syscall來獲取系統呼叫號,通過$arg1,$arg2等來獲取相應的引數值。

在probe使用者程式,系統呼叫或核心函式時,可以通過pa

rms來

獲取所有

的引數(

是字串

,不是具

體的值)

。在使用

「pro

besy

scal

l.名稱

」來pr

obe系

統呼叫時

,可以使

用arg

str來

獲取引數

列表,和

parms顯示格式不同,直接顯示對應的值。

4."."字元竄連線符

如果想將乙個函式返回的字串和乙個常量字串拼接,則在兩者之間加入"."即可,例如probefunc()."123"。

"."運算子還支援".=",即拼接後賦值。

5、獲取stap命令列引數

如果要獲取命令列引數準確的值,則使用$1、$2....$來獲取對應的引數。如果想將命令列引數轉換為字串,則使用@1、@2...@來獲取引數對應的字串。

6、next操作

如果在probe函式中,發現某個條件沒有滿足,則結束本次probe的執行,等待下次事件的到來。示例如下:

global i

probe begin

probe kernel.function(

"sys_read")  

printf(

"i = %d\n", i);

}

7、$$vars

如果合適的話,可以通過$$vars獲取當前所有可見的變數列表。如果列表中某些成員的值顯示"?",則表示當前這些變數尚未初始化,還不能訪問。

8、call和inline字尾的區別

如果加上call字尾,只有在當前probe的函式是非內聯函式時才會觸發事件。例如,如果在內聯函式pskb_may_pull()的probe點加上call字尾,則事件不會被觸發。對於非內聯函式的probe點,不能加上inline字尾,否則編譯時會報錯。如果想觸發內聯函式的probe事件,一定不能加上call字尾。如果call和inline字尾都不加,則核心函式和非內聯函式的probe事件都會觸發。

9、輸出"%"字元

在systemtap中使用轉義字元來輸出"%"沒有效果,在編譯時會報錯,可以使用"%%"來輸出"%"。

OpenGL GLSL 內建變數與 常用內建函式

在著色器中我們一般都會宣告變數來在程式中使用,但是著色器中還有一些特殊的變數,不宣告也可以使用。這些變數叫做內建變數。內建變數,相當於著色器硬體的輸入和輸出點,使用者利用這些輸入點輸入之後,就會看到螢幕上的輸出。通過輸出點可以知道輸出的某些資料內容。當然,實際上肯定不會這樣簡單,這麼說只是為了幫助理...

常用巨集 模板

if defined afx ttemplate h 2a080896 4b61 4dd2 a462 61957d494003 included define afx ttemplate h 2a080896 4b61 4dd2 a462 61957d494003 included include ...

DirectX常用巨集

收集於網路 一 多重取樣 列舉 d3dmultisample type 極別選擇 d3dmultisample none 禁用s d3dmultisample 1 sample d3dmultisample 2 sample d3dmultisample 3 sample d3dmultisampl...