好吧,在访问 之后gdb
,我发现问题出现在dtrace
' 函数中(我认为,dt_module_getctf
称为 via和)。在其中,我注意到大多数调用都会传播属性/变量;但是当失败发生时,我会得到!dtrace_symbol_type
dt_module_lookup_by_name
dm_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)
...