我在挫折中写的更少 - 但谁知道,也许有办法解决这个问题......
我想分析一下ALSA函数会发生什么,比如说snd_pcm_readi
;为了这个目的,让我说我准备了一个小testprogram.c
,我有这个:
void doCapture() {
ret = snd_pcm_readi(handle, buffer, period_size);
}
这个函数的问题是它最终(应该)挂钩到共享系统库snd_pcm_readi
中的/usr/lib/libasound.so
;从那里,我相信通过ioctl
,它会以某种方式与内核模块snd_pcm_read
中的/lib/modules/$(uname -r)/kernel/sound/core/snd-pcm.ko
进行通信 - 这应该最终与任何.ko
内核模块进行通信。特定声卡的驱动程序。
现在,通过上述组织,我可以做类似的事情:
valgrind --tool=callgrind --toggle-collect=doCapture ./testprogram
...然后kcachegrind callgrind.out.12406
确实揭示了snd_pcm_readi
,libasound.so
和ioctl
之间的关系(我无法获得与之相关的相同信息callgrind_annotate
) - 因此有点覆盖了用户空间;但就目前而言。此外,它产生一个调用图,也就是说函数之间的一般调用者/被调用者关系(可能是每个函数按计划工作的样本/滴答计数)。
但是,我希望得到的是类似于ftrace
跟踪器function_graph
的输出,它提供了跟踪内核函数的带时间戳的进入和退出... ftrace: add documentation for function graph tracer [LWN.net]:
$ cat /sys/kernel/debug/tracing/trace
# tracer: function_graph
#
# TIME CPU DURATION FUNCTION CALLS
# | | | | | | | |
2105.963678 | 0) | mutex_unlock() {
2105.963682 | 0) 5.715 us | __mutex_unlock_slowpath();
2105.963693 | 0) + 14.700 us | }
2105.963698 | 0) | dnotify_parent() {
( NB:较新的ftrace
文档似乎不首先显示function\_graph
的时间戳,只有持续时间 - 但我认为仍然可以修改该)
使用ftrace
,可以过滤,因此只能跟踪给定内核模块中的函数 - 所以在我的情况下,我可以添加snd-pcm.ko
的函数和任何.ko
模块是声卡驱动程序,我会在内核空间中找到有趣的东西。但是,我失去了用户空间程序的链接(,除非我明确printf
到/sys/kernel/debug/tracing/trace_marker
,或者从用户空间trace_printk
文件做.c
)
最终,我想要的是,有可能指定一个可执行文件,可能还有库文件和内核模块 - 并获得一个带时间戳的函数图(带有缩进/嵌套的入口和每个函数的出口),如{{1提供。这样的事情还有其他选择吗? (注意我可以在没有函数退出的情况下生活 - 但我真的想要有时间戳功能条目)
作为一个PS:我似乎找到了符合描述的东西,即ftrace
应用程序/脚本:
fulltrace跟踪ELF程序的执行,提供其用户空间,库和内核函数调用的完整跟踪。 ...
(先决条件)必须将以下内核配置选项及其依赖项设置为enabled(= y):FTRACE,TRACING_SUPPORT,UPROBES,UPROBE_EVENT,FUNCTION_GRAPH_TRACER。
听起来很完美 - 但问题是,我在Ubuntu 11.04上,而这个fulltrace
内核幸运地启用了2.6.38
- 它的CONFIG_FTRACE=y
甚至没有提到/boot/config-`uname -r`
:/因为我想避免做内核黑客攻击,不幸的是我不能使用这个脚本......
(顺便说一句,如果UPROBES可用,(据我所知),在符号地址上设置跟踪探测(从UPROBES
获得),输出再次转到{{1 - 所以使用UPROBES可以实现一些自定义解决方案,即使没有objdump -d
脚本)
所以,稍微缩小我的问题 - 是否有一个解决方案,允许同时用户空间(包括共享库)和内核空间“函数图”跟踪,但/sys/kernel/debug/tracing/trace
不是在内核中可用吗?