2013-08-16 56 views
0

我們可以像在內核空間中的函數 一樣轉儲用戶空間函數的函數參數嗎?如果我們 做dtrace -l -f -v,FBT提供者是否可以爲用戶空間函數轉儲參數?FreeBSD用戶空間用戶空間的DTrace和轉儲函數參數

我DTrace'ing「頂」工具,(「頂」實用兼具 周大福和矮調試節中創建的目標文件中)

我想通過視察「叫get_system_info功能頂」,我 確認存在被探測

root% dtrace -l | grep get_system_info 
55154 pid8488  top  get_system_info entry 

但我不能轉儲函數的自變量...

root% dtrace -l -f get_system_info -v 
    ID PROVIDER   MODULE       FUNCTION NAME 
55154 pid8488    top     get_system_info entry 

     Probe Description Attributes 
       Identifier Names: Private 
       Data Semantics: Private 
       Dependency Class: Unknown 

     Argument Attributes 
       Identifier Names: Private 
       Data Semantics: Private 
       Dependency Class: Unknown 

     Argument Types 
       None 

測試用一個簡單的腳本,

pid8488::get_system_info:entry 
{ 
    this->info = (struct system_info *)copyin(args[0], sizeof(struct system_info)); 
} 

...如果我用的是ARGS [0]符號,它說以下,

dtrace: failed to compile script top_d.d: line 17: index 0 is out of 
range for pid8488::get_system_info:entry args[ ] 

相反,如果我爲arg0取代,它編譯但值不是 必然是理智的。 示例結構system_info的ncpus成員顯示垃圾值。

完整的劇本是

pid8488::get_system_info:entry 
{ 
    this->info = (struct system_info *)copyin(arg0, sizeof(struct system_info)); 
    printf("last pid [%d] \n", this->info->last_pid); 
} 
pid8488::get_process_info:entry 
{ 
    this->info = (struct system_info *)copyin(arg0, sizeof(struct system_info)); 
    printf("ncpus [%d] \n", this->info->ncpus); 
} 

運行此

55154   get_system_info:entry last pid [8513] 
55155   get_process_info:entry ncpus [134558720] 

應該是顯示CPU的數量?任何腳本錯誤?

回答

0

我已經在9.1和9.2-RC2上進行了研究,但是我無法正確地使DTrace正常工作,所以我的註釋基於Solaris版本,應該大致相同。

fbt提供程序處理內核函數。它的用戶土地等同物是pid提供者。

pid提供程序當然可以公開函數參數,但除非FreeBSD的DTrace支持用戶登陸CTF,否則它們的類型將不可用。這可能是爲什麼你發現鍵入的args[n]不可用,而你被限制爲整數argn

我猜測功能get_system_info()填充struct system_info。如果是這種情況,那麼您必須在之後複製結構中的函數。 另外,如果dtrace(1)找不到該結構的定義,那麼您必須自己提供它,方法是包含它或適當的頭文件(並使用-C標誌)。 下面是一個(未測試)實施例:

 
struct system_info { 
    ... 
    unsigned int ncpus; 
    ... 
}; 

pid$target::get_system_info:entry 
{ 
    self->siup = (uintptr_t)arg0;  /* user-land pointer */ 
} 

pid$target::get_system_info:return 
/self->siup/ 
{ 
    this->sikp = (struct system_info *) /* kernel pointer */ 
     copyin(self->siup, sizeof (struct system_info)); 
    printf("ncpus = %d\n", this->sikp->ncpus); 
    self->siup = 0;    /* free thread-local storage */ 
} 

最後,評估數據類型時(例如,指針的大小),則dtrace(1)將 默認到正在運行的內核的數據模型。如果您正在運行64位內核,但您正在測試32位進程,那麼請使用「-32」標誌,以便dtrace(1)爲它所看到的各種類型使用適當的大小。