Linux源码 tracepoints
阅读数:274 评论数:0
跳转到新版页面分类
Linux
正文
一、概述
在 Linux 内核中,tracepoints 提供了一种机制来监控和记录系统运行时的特定点的信息,这对于调试和性能分析是非常有用的。Tracepoints 被设计为对系统性能的影响最小,即使在生产系统中也可以使用。
Tracepoints 是内核中预定义的静态探针点,开发者可以在这些点上注册回调函数,这些回调函数在运行时被调用以收集数据。Tracepoints 被广泛用于各种内核跟踪工具,比如 ftrace、perf 和 eBPF(Extended Berkeley Packet Filter)。
二、使用Tracepoints
要使用 tracepoints,你需要有一个内核,它被编译时包含了 tracepoint 支持(通常默认开启)。以下是使用 tracepoints 的一般步骤:
1、启用Tracepoints
确保内核配置中启用了 tracepoints。这通常是默认的,但可以通过内核配置选项 CONFIG_TRACEPOINTS
来确认。
2、查找可用的Tracepoints
系统中的可用 tracepoints 通常位于 /sys/kernel/debug/tracing/events
目录下,你可以浏览这个目录查看可用的 tracepoints。
3、启动Tracepoints
要启动一个特定的 tracepoint,你需要写入其对应的 enable
文件。例如:
echo 1 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable
4、收集跟踪数据
启用 tracepoint 后,相关数据会被记录到 ring buffer 中,你可以从 /sys/kernel/debug/tracing/trace
文件中读取这些数据。
5、停止Tracepoints
当你完成数据收集后,可以通过将 0 写入 enable
文件来停止 tracepoint。
echo 0 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable
三、内核中的相关描述
具体的可以参考kernel文章, 路径: Documentation/trace里面的tracepoints.txt和tracepoint-analysis.txt.
内核的每个tracepoint提供一个钩子来调用probe函数. 一个tracepoint可以打开或关闭.打开时, probe函数关联到tracepoint, 关闭时, probe函数不关联到tracepoint. tracepoint关闭时对kernel产生的影响很小, 只是增加了极少的开销(一个分支判断), 极小的空间开销(一条函数调用语句和几个数据结构 ). 当一个tracepoint打开时, 用户提供的probe函数在每次这个tracepoint执行时都会被调用.
如果用户准备为kernle加入新的tracepoint, 每个tracepoint必须以下列格式声明:
#include <linux/tracepoint.h>
DECLARE_TRACE(tracepoint_name,
TPPROTO(trace_function_prototype),
TPARGS(trace_function_args));
上面的宏定义了一个新的tracepoint叫tracepoint_name.与这个tracepoint关联的probe函数必须与TPPROTO定义的函数prototype一致, probe函数的参数列表必须与TPARGS宏定义的一致.
或许用一个例子来解释比较容易理解. Kernel里面已经包含了一些tracepoints, 其中一个叫做sched_wakeup, 这个tracepoint在每次scheduler唤醒一个进程时都会被调用. 它是这样定义的:
DECLARE_TRACE(sched_wakeup,
TPPROTO(struct rq *rq, struct task_struct *p),
TPARGS(rq, p))
实际在kernle中插入这个tracepoint点的是一行如下代码:
trace_sched_wakeup(rq, p);
注意, 插入tracepint的函数名就是将trace_前缀添加到tracepoint_name的前面.除非有一个实际的probe函数关联到这个tracepoint, trace_sched_wakeup() 这个只是一个空函数.下面的操作就是将一个probe函数关联到一个tracepoint
void my_sched_wakeup_tracer(struct rq *rq, struct task_struct *p);
register_trace_sched_wakeup(my_sched_wakeup_tracer);
register_trace_sched_wakeup()函数实际上是DEFINE_TRACE()定义的,它把probe函数my_sched_wakeup_tracer()和tracepoint sched_wakeup关联起来.
四、工具和接口
- ftrace:是内核自带的功能强大的跟踪工具,可以用来启用和禁用 tracepoints,以及查看跟踪结果。
- perf:是一个性能分析工具,它也可以使用 tracepoints 来收集关于系统和应用程序性能的数据。
- eBPF:是一种高级的跟踪和监控技术,它可以与 tracepoints 配合使用,以实现复杂的数据采集和报告逻辑。
五、注意事项
- 性能影响:虽然 tracepoints 的设计尽量减小了性能影响,但启用大量的 tracepoints 或者在高频率触发的 tracepoints 上收集数据仍然可能对系统性能有所影响。
- 安全性:因为 tracepoints 可以暴露大量的内核运行时信息,所以在生产环境中使用时需要考虑安全性。