自定义创建Linux内核Tracepoint
自定义创建Linux内核Tracepoint
1.前言
在Linux内核开发中,TracePoints是一种强大的调试和性能分析工具。但是在我们实际开发过程中,我们经常会遇到没有我们想要的TracePoints。今天我们将介绍如何在内核中插入自定义跟踪点。
2. 自定义Tracepoint创建步骤
我们如上图所示在sched目录下新建一个tracetest目录,在该目录下我们创建三个文件,如下:
2.1 定义Tracepoint头文件
/*trace_my_events.h*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM my_events#if !defined(_TRACE_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_EVENTS_H#include <linux/tracepoint.h>/* 定义自定义tracepoint */
TRACE_EVENT(my_custom_event,TP_PROTO(int param1, const char *param2, u64 param3),TP_ARGS(param1, param2, param3),TP_STRUCT__entry(__field(int, param_a)__array(char, param_b, TASK_COMM_LEN)__field(u64, param_c)),TP_fast_assign(__entry->param_a = param1;memcpy(__entry->param_b, param2, TASK_COMM_LEN);__entry->param_c = param3;),TP_printk("param1=%d param2=%s param3=%llu",__entry->param_a, __entry->param_b, __entry->param_c)
);#endif#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH ../../kernel/sched/tracetest
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE trace_my_events#include <trace/define_trace.h>
2.2 实现Tracepoint注册
/*trace_test.c*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/tracepoint.h>
#include <linux/jiffies.h>
#include <linux/delay.h>#define CREATE_TRACE_POINTS
#include "trace_my_events.h"void my_trace_function(int p1, const char *p2, unsigned long p3);void my_trace_function(int p1, const char *p2, unsigned long p3)
{/* 触发tracepoint */trace_my_custom_event(p1, p2, p3);
}static int __init my_trace_init(void)
{int i = 0;printk(KERN_INFO "Testing custom tracepoints...\n");while (1) {my_trace_function(i, "test-string", jiffies_to_msecs(jiffies));msleep(1000);if (i >= 9000) {i = 0;}}return 0;
}static void __exit my_trace_exit(void)
{printk(KERN_INFO "My Trace Module Exited\n");return;
}module_init(my_trace_init);
module_exit(my_trace_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Trace");
MODULE_DESCRIPTION("Tracepoint Example Module");
2.3 Makefile实现
# Makefile
obj-m += mytrace.o
mytrace-y += trace_test.o
2.4 添加tracetest模块到内核
在sched目录的Makefile文件中添加tracetest模块
obj-m += tracetest/
3. 编译验证
3.1 编译内核
接下来我们开始编译内核,内核编译流程我们在前面的文章已经讲过,我们执行如下指令
make -j8 //-j代表CPU的个数
//查看CPU的个数
screenfetch
编译成功如下:
3.2 加载ko模块
因为我们的代码是一个.ko模块,需要手动加载模块后才会创建tracepoint节点:
# 加载模块
insmod ./mytrace.ko# 查看模块是否加载成功
lsmod | grep mytrace
为了便于观测,我们在mytrace.ko中加入死循环(while(1)),所以该模块不会结束
我们直接开启一个新终端验证
3.3 验证tracepoint
我们先使能my_events的enable。
cd /sys/kernel/tracing/events/my_events/my_custom_event
cat enable
echo 1 > enable
cat enable
接着我们来进行tracepoint观测
cd /sys/kernel/tracing
cat available_events | grep custom
echo my_events:my_custom_event >> set_event
cat set_event | grep my_custom_event
echo 0 > tracing_on
echo > trace
echo 1 > tracing_on
cat trace | grep custom
好了,到这里就结束了,我们最后把这个ko模块销毁就行。