【调试】ftrace(二)新增跟踪点
内核的各个子系统已经有大量的跟踪点,如果这些跟踪点无法满足工作中的需求,可以自己手动添加跟踪点。
添加跟踪点有两种方式,一种是仿照events/
目录下的跟踪点,使用TRACE_EVENT()
宏添加。另一种是参考内核目录samples/trace_events
添加。本文对这两种方式分别进行介绍。
使用 TRACE_EVENT 定义 tracepoint
我们仿照events/timer/timer_start
,添加一个timer_stat
的跟踪点,获取start_pid
和slack
参数。
首先,需要在include/trace/events/timer.h
头文件种添加名为timer_stat
的跟踪点。
/**
* timer_stat - ftrace interface timer_stat
* @timer: pointer to struct timer_list
*/
TRACE_EVENT(timer_stat,
TP_PROTO(struct timer_list *timer),
TP_ARGS(timer),
TP_STRUCT__entry(
__field( void *, timer )
__field( int, start_pid )
__field( int, slack)
),
TP_fast_assign(
__entry->timer = timer;
__entry->start_pid = timer->start_pid;
__entry->slack = timer->slack;
),
TP_printk("ftrace interface timer_stat:timer=%p pid=%d slack=%d\n",
__entry->timer,__entry->start_pid,__entry->slack)
);
TRACE_EVENT()
宏如下
#define TRACE_EVENT(name, proto, args, struct, assign, print) \
DEFINE_TRACE(name)
- name:表示跟踪点的名字,如上面的timer_stat。
- proto:表示跟踪点调用的入参的原型,比如
timer
类型为struct timer_list *
。 - args:表示参数。
- struct:定义跟踪器内部使用的
__entry
数据结构。 - assign:把参数复制到
__entry
数据结构中。 - print:定义输出的格式。
接着在kernel/kernel/time/timer.c
debug_activate()
添加trace_timer_stat()
。
static inline void
debug_activate(struct timer_list *timer, unsigned long expires)
{
debug_timer_activate(timer);
trace_timer_start(timer, expires, timer->flags);
trace_timer_stat(timer);
}
重新编译内核后,烧写到设备中,即可看到sys
节点已经有了新增的跟踪点。
使能跟踪点后,查看trace点的输出。
编译为独立的ko文件
内核还提供了一个跟踪点的例子,在samples/trace_events
目录下。
trace_event_init()
创建内核线程一个名为event-sample
内核线程。
static int __init trace_event_init(void)
{
simple_tsk = kthread_run(simple_thread, NULL, "event-sample");
if (IS_ERR(simple_tsk))
return -1;
return 0;
}
kthread_should_stop()
用于创建的线程检查结束标志,并决定是否退出。
static int simple_thread(void *arg)
{
int cnt = 0;
while (!kthread_should_stop())
simple_thread_func(cnt++);
return 0;
}
set_current_state()
来设置进程的状态,设置为TASK_INTERRUPTIBLE
表示是可以被信号和wake_up()
唤醒的,当信号到来时,进程会被设置为可运行。
schedule_timeout()
将当前task调度出cpu,重新调度间隔为HZ
。接着trace_
开头的函数就会依次打印跟踪点的信息。
static void simple_thread_func(int cnt)
{
int array[6];
int len = cnt % 5;
int i;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
for (i = 0; i < len; i++)
array[i] = i + 1;
array[i] = 0;
/* Silly tracepoints */
trace_foo_bar("hello", cnt, array, random_strings[len],
tsk_cpus_allowed(current));
trace_foo_with_template_simple("HELLO", cnt);
trace_foo_bar_with_cond("Some times print", cnt);
trace_foo_with_template_cond("prints other times", cnt);
trace_foo_with_template_print("I have to be different", cnt);
}
trace_foo_with_template_simple
跟踪点的实现方式也是使用的TRACE_EVENT ()
宏,这里不再赘述。
最后将文件编译为ko拷贝到设备上insmod
后,即可看到sys
目录下已经有新增的节点。
cd /home/zhongyi/code/rk3399_linux_release_v2.5.1_20210301/kernel/samples/trace_events
make -C /home/zhongyi/code/rk3399_linux_release_v2.5.1_20210301/kernel/ M=$(pwd) modules
root@firefly:/sys/kernel/debug/tracing# cat available_events | grep sample
sample-trace:foo_bar
sample-trace:foo_bar_with_cond
race:foo_bar_with_fn
sample-trace:foo_with_template_simple
sample-trace:foo_with_template_cond
sample-trace:foo_with_template_fn
sample-trace:foo_with_template_print
power:pstate_sample
root@firefly:/sys/kernel/debug/tracing# cd events/sample-trace/
root@firefly:/sys/kernel/debug/tracing/events/sample-trace# ls
enable foo_bar_with_cond foo_with_template_fn
filter foo_bar_with_fn foo_with_template_print
foo_bar foo_with_template_cond foo_with_templ_simple
root@firefly:/sys/kernel/debug/tracing/events/sample-trace# echo 1 > enable
root@firefly:/sys/kernel/debug/tracing/events/sample-trace# cat /sys/kernel/debug/tracing/trace
TRACE_EVENT_CONDITION()
在某些情况下,跟踪点只有在某个条件发生时才会被调用,类似于
if (cond)
trace_foo();
TRACE_EVENT_CONDITION()
宏就是这个作用,它和TRACE_EVENT()
相比只是在参数中多加了一个cond条件。TP_CONDITION()
会对条件做个判断。
TRACE_EVENT(name, proto, args, struct, assign, printk)
TRACE_EVENT_CONDITION(name, proto, args, cond, struct, assign, printk)
详细使用方法可以参考trace-events-sample.h
。
TRACE_EVENT_FN()
TRACE_EVENT_FN()
是在跟踪点使能前和使能后分别打印一些信息。相比于TRACE_EVENT()
,TRACE_EVENT_FN()
多了两个参数reg
和unreg
,
TRACE_EVENT(name, proto, args, struct, assign, printk)
TRACE_EVENT_FN( name, proto, args, struct, assign, printk, reg, unreg)
reg
和unreg
原型为
void reg(void)
reg
函数在跟踪点使能前打印,unreg
函数在跟踪点使能后打印。reg
和unreg
可以根据实际情况置其中一个为NULL,也可以全部置为NULL。
详细使用方法可以参考trace-events-sample.h
。
本文参考
samples/trace_events
【调试】ftrace(二)新增跟踪点的更多相关文章
- OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型
OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型 目录 背景介绍 请参考前文OpenGL ES 2.0 Shader 调试新思路(一): 改变提问方式 优化 ledCha ...
- win10 下visual studio 2015 在调试模式下不能跟踪源文件
win10 下visual studio 2015 在调试模式下不能跟踪源文件,只要一调试就会关闭(隐藏)打开的文档,非常不方便.经过一番折腾,发现是配置的问题. 如果安装多个版本的VS,请删除对应版 ...
- Visual Studio调试之避免单步跟踪调试模式
Visual Studio调试之避免单步跟踪调试模式 写完Visual Studio调试之断点进阶篇之后,想分享一下我常用的一些调试技巧,后面发现写之前,一些背景知识需要介绍一下. 下面是几篇今年2月 ...
- Delphi应用程序的调试(二)使用断点
Delphi应用程序的调试(二)使用断点 使用断点(Using Breakpoints) 当用户从Delphi IDE 运行程序时,程序全速运行,只会在设置了断点的地方停住. New Term 断点( ...
- 2018-2-13-visual-Studio-无法调试,提示程序跟踪已退出
title author date CreateTime categories visual Studio 无法调试,提示程序跟踪已退出 lindexi 2018-2-13 17:23:3 +0800 ...
- postgresql编译安装与调试(二)
接前文postgresql编译安装与调试(一),继续说说postgresql的编译安装与调试. 上一篇已经详细说明了如何在Linux系统上编译安装postgresql,这次我们在此基础上简单讲讲如何在 ...
- 使用 PHPStorm + Xdebug 实现断点调试(二)
一.配置 Xdebug 配置 Xdebug 相关参数,在 php.ini 文件中新增如下配置,如果没安装的,请参考<PHP 安装 Xdebug扩展>: [xdebug] xdebug.re ...
- numpy C语言源代码调试(二)
前一篇已经介绍,可以使用gdb进行调试,但是本人不太习惯gdb的文本界面,所以希望找一个比较好用的gdb的前端gui调试器. 想到的第一个是一个非常老的调试工具,DDD. DDD - Data Dis ...
- 如何调试SSIS包之跟踪变量赋值
在SSIS开发工具SQL Server Data Tools中提供了调试功能,可以让我们方便的跟踪参数赋值或者数据流条数.本文主要介绍了如何使用SSDT的调试功能. Part A: Script ta ...
- ASP.NET WEB API 中的路由调试与执行过程跟踪
路由调试 RouteDebugger 是调试 ASP.NET MVC 路由的一个好的工具,在ASP.NET WEB API中相应的有 WebApiRouteDebugger ,Nuget安装 Inst ...
随机推荐
- Centos8.4离线安装JDK+Tomcat+MySQL8.0+Nginx
一.安装JDK 注:以下命令环境在Xshell中进行. 1.查询出系统自带的OpenJDK及版本 rpm -qa | grep jdk 2.如果显示已安装openjdk则对其进行卸载. 输入:rpm ...
- SpringBoot启动@Test单元测试时,一致卡在加载junit-bom-5.6.3.pom.xml文件
今天做项目时创建一个SpringBoot工程,使用的版本是<spring-boot.version>2.3.7.RELEASE</spring-boot.version> 当我 ...
- JavaFx 打开一个新窗口和窗口交互(四)
JavaFx 打开一个新窗口和窗口交互(四) JavaFX 从入门入门到入土系列 前面我演示的demo都是单个窗口,那么如何实现多个窗口呢?使用Stage secondStage = new Stag ...
- 如何解决windos系统关闭nginx进程之后仍然可以访问?
1.停止Nginx服务的四种方法 从容停止服务 这种方法较stop相比就比较温和一些了,需要进程完成当前工作后再停止. nginx -s quit 立即停止服务 这种方法比较强硬,无论进程是否在工作, ...
- 创建傀儡进程svchost.exe并注入DLL文件(Shellcode)
本文主要利用 SetThreadContext 修改进程中的线程上下文来实现Dll注入(ShellCode). 实现原理 首先,使用 CreateProcess 函数创建svchost.exe进程,并 ...
- 云小课|MRS基础操作之集群健康检查
本文分享自华为云社区<云小课|MRS基础操作之集群健康检查>,作者:阅识风云. 阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视 ...
- 《低代码发展白皮书(2022年)》&《2022低代码·无代码应用案例汇编》,发布了
摘要:信息通信研究院云计算与大数据研究所副所长栗蔚发布了<低代码发展白皮书(2022年)>&<2022低代码·无代码应用案例汇编>. 本文分享自华为云社区<华为参 ...
- 【CVPR2022】用于域适应语义分割的域无关先验
摘要:本文给大家分享一篇我们在CVPR 2022 上发表的paper:Domain-Agnostic Prior for Transfer Semantic Segmentation.文章提出了一种图 ...
- 一键自动修改和翻新OC源码,解决苹果审核4.3和马甲问题
ipaguard 自动修改/翻新/混淆/OC/iOS代码,自动替换类名,方法名 由来 网上有很多关于如何混淆iOS源码的方法,但是都不够智能,生成的方法类名要么千奇百怪,要么aaaabbbxxx这 ...
- appuploder全过程使用教程(Windows版本)
转载:使用appuploader工具流程(Windows版本) 一.登录apple官网,注册账号 1.注册苹果账号 Sign In - Apple 2.登录开发者中心 ,出现协议弹框,同意即可. 二. ...