2010-02-02 58 views
3

DTrace是最初來自Solaris的令人印象深刻的強大的跟蹤系統,但它被移植到FreeBSD和Mac OSX。從DTrace腳本調用C函數

DTrace的使用稱爲d高級語言沒有什麼不同AWK或C.下面是一個例子:

io:::start 
/pid == $1/ 
{ 
    printf("file %s offset %d size %d block %llu\n", args[2]->fi_pathname, 
     args[2]->fi_offset, args[0]->b_bcount, args[0]->b_blkno); 
} 

使用命令行sudo dtrace -q -s <name>.d <pid>所有IO源於該過程被記錄下來。

我的問題是如何以及如何從DTrace腳本中調用自定義C函數,以便在跟蹤過程中對跟蹤數據執行高級操作。

回答

6

DTrace explicity阻止您做這樣的事情,原因與您無法在D中編寫循環的原因相同:如果以任何方式,形狀或形式擰緊它,您會使整個系統崩潰。當D探頭髮射時,您處於KERNEL模式,而不是userland。讓我引用「Linux內核模塊編程指南」:

所以,你要編寫一個內核模塊。你知道C,你已經寫了一些 正常程序作爲進程運行,現在你想要到達真正的 動作的位置,一個野指針可以擦除你的文件系統,一個 核心轉儲意味着重啓。

這就是爲什麼你不想在D探針中扮演牛仔,爲什麼D的限制對你有好處。 =]

1

您應該能夠在每個探測器用管道觸發後至少過濾dtrace的輸出。

 
sudo dtrace -n 'proc:::exec-success { trace(curpsinfo->pr_psargs); }' | perl myscript.pl

myscript.pl:

#!/usr/bin/perl 
while (<>){ 
print $_; 
print "another application launched, do something!"; 
}

1

這是不可能從您的探測器爲@Sniggerfardimungus提到的原因的內部調用任意C,但想必你只想做一些操作與同時是數據收集(將其存儲在數據庫中/使用它/進行一些計算或可視化),這完全有可能來自C(以及通過圍繞幾個其他語言的C的包裝)。

要做到這一點,請使用libdtrace(標題在我的Mac OS X框中的/usr/include/dtrace.h)或其包裝器(如node-libdtrace)。基本思想是您可以構建您自己的DTrace數據使用者(實際上替換dtrace(1m)命令行工具),該工具從正在運行的任何腳本接收輸出。一旦你有了數據,你可以隨心所欲地做任何事情。

1

編輯我原來的答案還不夠,但您也可以在DTrace腳本中使用system()命令生成一個在DTrace中發生事件時運行任意代碼的子流程。這是潛在的destructive action,所以您必須在D腳本中使用-w命令行選項或#pragma D option destructive指令。請注意,破壞性操作可能會掛起,無限循環,殺死並以其他方式破壞您正在探查的進程,如果您不仔細使用它們。 (我不會推薦使用內核的破壞性行爲,除非你真的不在乎你的系統在意外搞砸時是否會關閉。)

你可以使用腳本運行system()來調用你的任意C代碼或發送信號給另一個進程來調用它等)。