如何使用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 –