修复Linux中dtrace的“无符号类型信息”?

时间:2013-07-27 21:31:47

标签: linux dtrace

记录下来:(自我回答)

我知道由于许可问题,Sun的dtrace没有为Ubuntu打包;所以我下载了它并在Ubuntu上从源代码构建它 - 但是我遇到的问题非常像Simple dtraces not working · Issue #17 · dtrace4linux/linux · GitHub中的问题;即加载驱动程序似乎很好:

dtrace-20130712$ sudo make load
tools/load.pl
23:20:31 Syncing...
23:20:31 Loading: build-2.6.38-16-generic/driver/dtracedrv.ko
23:20:34 Preparing symbols...
23:20:34 Probes available: 364377
23:20:44 Time: 13s

...但是,如果我尝试运行一个简单的脚本,它就会失败:

$ sudo ./build/dtrace -n 'BEGIN { printf("Hello, world"); exit(0); }'
dtrace: invalid probe specifier BEGIN { printf("Hello, world"); exit(0); }: "/path/to/src/dtrace-20130712/etc/sched.d", line 60: no symbolic type information is available for kernel`dtrace_cpu_id: Invalid argument

根据上面的问题链接:

  

(ctf需要一个私有且有效的libdwarf库 - 大多数旧版本都有破坏版本。)

...然后我从源代码构建libdwarf,然后基于它构建dtrace(非常简单,需要手动查找符号链接的正确位置);我仍然遇到同样的失败。

有可能解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

嗯,在访问gdb之后,我发现问题发生在dtrace的函数dt_module_getctf中(通过dtrace_symbol_type调用,我认为dt_module_lookup_by_name 1}})。在其中,我注意到大多数调用传播属性/变量dm_name = "linux";但是当失败发生时,我会得到dm_name = "kernel"

请注意sched.d的原始第60行是:

    cpu_id = `dtrace_cpu_id; /* C->cpu_id; */

然后我找到thr3ads.net - dtrace discuss - accessing symbols without type info [Nov 2006];提到此错误消息的位置:

  

dtrace:无效的探测器说明符fbt :: calcloadavg:entry {   printf(“CMS_USER:%d,CMS_SYSTEM:%d,cpu_waitrq:%d \ n”,   `cpu0.cpu_acct [0],`cpu0.cpu_acct [1],`cpu0.cpu_waitrq);}:在行动   list:没有符号类型信息可用于unix`cpu0:没有类型   可用于符号的信息

所以:

  • 在该系统上,请求`cpu0.cpu_acct[0]已解析为unix`cpu0;
  • 在我的系统上,请求`dtrace_cpu_id已解析为kernel`dtrace_cpu_id

因为“使用反引号运算符来读取 内核变量的值,这将特定于正在运行的内核。“(howto measure CPU load - DTrace General Discussion - ArchiveOrange),我认为可能明确地将这个”反引号变量“”转换“给linux会有所帮助。

事实确实如此 - 只有sched.d的一小部分需要更改为:

translator cpuinfo_t < dtrace_cpu_t *C > {
    cpu_id = linux`dtrace_cpu_id; /* C->cpu_id; */
    cpu_pset = -1;
    cpu_chip = linux`dtrace_cpu_id; /* C->cpu_id; */
    cpu_lgrp = 0; /* XXX */
/*  cpu_info = *((_processor_info_t *)`dtrace_zero); /* ` */ /* XXX */
};

inline cpuinfo_t *curcpu = xlate <cpuinfo_t *> (&linux`dtrace_curcpu);

......然后突然 - 它开始工作了!:

dtrace-20130712$ sudo ./build/dtrace -n 'BEGIN { printf("Hello, world"); exit(0); }'
dtrace: description 'BEGIN ' matched 1 probe
CPU     ID                    FUNCTION:NAME
  1      1                           :BEGIN Hello, world

PS:

Protip 1:永远不会dtrace -n '::: { printf("Hello"); }' - 这意味着“在每个内核事件上执行printf”,它将完全冻结内核; CTRL-Alt-Del甚至都不会工作!

Protip 2:如果您想在Debugging DTrace中使用DTRACE_DEBUG,请使用sudo -E

dtrace-20130712$ DTRACE_DEBUG=1 sudo -E ./build/dtrace -n 'BEGIN { printf("Hello, world"); exit(0); }'
libdtrace DEBUG: reading kernel .ctf: /path/to/src/dtrace-20130712/build-2.6.38-16-generic/linux-2.6.38-16-generic.ctf
libdtrace DEBUG: opened 32-bit /proc/kallsyms (syms=75761)
...