Dtrace 中的局部变量

Posted

技术标签:

【中文标题】Dtrace 中的局部变量【英文标题】:Local Variables in Dtrace 【发布时间】:2017-03-28 10:04:31 【问题描述】:

如何使用 dtrace 访问函数的本地变量?

比如下面的sn-p我想用dtrace知道变量x的值。

void foo(int a)
     int x=some_fun(a);

【问题讨论】:

【参考方案1】:

内核代码无法跟踪局部变量,因为没有检测任意内核指令的机制。即使在用户领域,跟踪局部变量也有些复杂,因此,对于您给出的具体示例,跟踪 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;

并使用 DWARF 将其构建为 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 -24DW_OP_fbreg 本身必须是 由父函数的DW_AT_frame_base 的结果替换 属性,即DW_OP_reg6。 DWARF 使用自己的架构无关 寄存器编号和到各个寄存器的映射最多 适当的标准机构。在这种情况下,AMD64 ABI 告诉 我们认为 DWARF 寄存器 6 对应于%rbp。因此x 存储在 %rbp - 0x18。 (有关 DWARF 本身的更多信息,我推荐 Michael Eager 的 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 探针添加到源代码中会容易得多。见ibm.com/developerworks/aix/library/au-dtraceprobes.html 和blogs.oracle.com/d/entry/adding_dtrace_probes_to_user

以上是关于Dtrace 中的局部变量的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的“局部变量”是啥意思?

C语言中的 局部变量,存储在啥地方?

C++中的全局变量普通局部变量和静态局部变量的区别

java中成员变量和局部变量在内存中的分配

python中的命名空间作用域全局变量与局部变量

C语言中的局部变量和全局变量