1

只是记录这一点:(自我回答跟随)

我知道dtrace由于许可问题,Sun 没有为 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基于它(不是微不足道的,需要手动找到符号链接的正确位置);我仍然遇到同样的失败。

有可能解决这个问题吗?

4

1 回答 1

1

好吧,在访问 之后gdb,我发现问题出现在dtrace' 函数中(我认为,dt_module_getctf称为 via和)。在其中,我注意到大多数调用都会传播属性/变量;但是当失败发生时,我会得到!dtrace_symbol_typedt_module_lookup_by_namedm_name = "linux"dm_name = "kernel"

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

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

然后我发现thr3ads.net - dtrace 讨论 - 访问没有类型信息的符号 [2006 年 11 月];提到此错误消息的地方:

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);}:在动作列表中:没有可用于 unix 的符号类型信息`cpu0:没有可用于符号的类型信息

所以:

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

而且由于“反引号运算符用于读取内核变量的值,这将特定于正在运行的内核。 ”(如何测量 CPU 负载 - DTrace 一般讨论 - 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:如果要DTRACE_DEBUG调试 DTrace中使用,请使用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)
...
于 2013-07-27T21:49:17.930 回答