在 Linux 中修复 dtrace 中的“无符号类型信息”?
Posted
技术标签:
【中文标题】在 Linux 中修复 dtrace 中的“无符号类型信息”?【英文标题】:Fixing 'no symbolic type information' from dtrace in Linux? 【发布时间】:2013-07-27 21:31:46 【问题描述】:仅记录此内容:(自行回答)
我知道由于许可问题,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】:好吧,在访问gdb
之后,我发现问题出现在dtrace
的函数dt_module_getctf
(通过dtrace_symbol_type
调用,我认为是dt_module_lookup_by_name
)。在其中,我注意到大多数调用都会传播属性/变量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);: 在行动 列表:没有符号类型信息可用于 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)
...
【讨论】:
以上是关于在 Linux 中修复 dtrace 中的“无符号类型信息”?的主要内容,如果未能解决你的问题,请参考以下文章