如何使用dtrace訪問函數本地的函數?Dtrace中的局部變量
例如,在下面的代碼片段中,我想通過dtrace知道變量x的值。
void foo(int a){
int x=some_fun(a);
}
如何使用dtrace訪問函數本地的函數?Dtrace中的局部變量
例如,在下面的代碼片段中,我想通過dtrace知道變量x的值。
void foo(int a){
int x=some_fun(a);
}
跟蹤局部變量對於內核代碼是不可能的,因爲沒有任何機制來檢測任意內核指令。即使在user-land中,跟蹤局部變量也有些複雜,因此,對於您給出的具體示例,跟蹤some_fun()
的返回值會更有意義。
如果你必須跟蹤任意的局部變量,那麼你將需要確定它在特定關注點的位置(通常是寄存器或內存中的位置)。對於簡單的情況,您可以通過分解功能並檢查輸出來完成此操作。對於更復雜的情況,使用DWARF構建對象可能會很有幫助,然後查找本地變量的DIE的DW_AT_location
屬性。
你發現變量的位置,你需要用D表示它;請注意,寄存器通過uregs[]
陣列暴露。此外,由於dtrace(1)
無法理解行號,因此需要使用函數內的偏移量來描述探針。有關更多信息,請參閱Oracle Solaris Dynamic Tracing Guide中的「用戶進程跟蹤」部分。
舉個例子,我寫了包含
int
foo(int i)
{
int x;
...
for (x = 0; x < 10; x++)
i += 2;
一個簡單的程序,並建立了它,作爲一個AMD64可執行文件,而且矮...
cc -m64 -g -o demo demo.c
...尋找foo()
前其定義爲x
輸出 的dwarfdump demo
:
< 1><0x000000e4> DW_TAG_subprogram
DW_AT_name "foo"
...
DW_AT_frame_base DW_OP_reg6
< 2><0x00000121> DW_TAG_variable
DW_AT_name "x"
...
DW_AT_location DW_OP_fbreg -24
x
被描述爲DW_OP_fbreg -24
但DW_OP_fbreg
本身必須是 由父功能的DW_AT_frame_base
屬性的結果被取代,即DW_OP_reg6
。 DWARF使用其自己的體系結構不可知的 編號爲寄存器和映射到單個寄存器是高達 適當的標準體。在這種情況下,AMD64 ABI告訴 us DWARF寄存器6對應於%rbp
。因此x
存儲在 %rbp - 0x18
。 (欲瞭解更多有關矮本身,我建議邁克爾·伊格的 Introduction to the DWARF Debugging Format)
因此,如果你已經發現,源在你 感興趣的是線的偏移0x32(或許通過檢查DWARF 線表)那麼你可能會寫這樣一探頭:
pid$target:a.out:foo:32
{
self->up = (uintptr_t)(uregs[R_RBP] - 0x18);
self->kp = (int *)copyin(self->up, sizeof (int));
printf("x = %d\n", *self->kp);
self->up = 0;
self->kp = 0;
}
這是我所看到的,當我運行演示程序:
# dtrace -q -s test.d -c /tmp/demo
x = 1
x = 2
x = 3
x = 4
x = 5
x = 6
x = 7
x = 8
x = 9
x = 10
#
我斗膽這是一個容易得多DTrace探測器添加的源代碼,如果pos錫布爾赫丁。請參閱http://www.ibm.com/developerworks/aix/library/au-dtraceprobes.html和https://blogs.oracle。COM/d /項/ adding_dtrace_probes_to_user –