当前位置: 首页 > news >正文

浅析Linux追踪技术之ftrace:Tracepoint

文章目录

    • 概述
    • Tracepoint使用
      • 定义Tracepoint
      • 添加Tracepoint调用
    • Tracepoint数据结构
    • TRACE_EVENT实现
      • DECLARE_TRACE
      • __DECLARE_TRACE
    • trace_xxx函数
    • 相关参考

概述

Tracepoint(跟踪点)是添加到代码流程中的调用点,并且允许开发者注册自定义的回调函数执行。默认情况下,跟踪点是关闭的状态,不会对原代码逻辑造成影响;当跟踪点为开启状态时,每次运行到跟踪点,都会调用开发者注册的回调函数。

Tracepoint使用

开发者使用Tracepoint需要进行两个步骤:

  1. 定义Tracepoint;
  2. 在代码流程中添加对跟踪点的调用。

定义Tracepoint

Linux内核使用TRACE_EVENT宏来定义以及向系统中添加一个Tracepoint,使用方式如下:

TRACE_EVENT(block_rq_complete,TP_PROTO(struct request *rq, int error, unsigned int nr_bytes),TP_ARGS(rq, error, nr_bytes),TP_STRUCT__entry(__field(  dev_t,	dev			)__field(  sector_t,	sector			)__field(  unsigned int,	nr_sector		)__field(  int,		error			)__array(  char,		rwbs,	RWBS_LEN	)__dynamic_array( char,	cmd,	1		)),TP_fast_assign(__entry->dev	   = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;__entry->sector    = blk_rq_pos(rq);__entry->nr_sector = nr_bytes >> 9;__entry->error     = error;blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, nr_bytes);__get_str(cmd)[0] = '\0';),TP_printk("%d,%d %s (%s) %llu + %u [%d]",MAJOR(__entry->dev), MINOR(__entry->dev),__entry->rwbs, __get_str(cmd),(unsigned long long)__entry->sector,__entry->nr_sector, __entry->error)
);

其中:

  • block_rq_complete为跟踪点名称;
  • TP_PROTO部分定义了跟踪点回调函数原型;
  • TP_ARGS部分定义了回调函数的参数;
  • TP_STRUCT__entry部分定义了跟踪程序可以使用的数据结构,
  • TP_fast_assign部分描述了传递数据的方式;
  • TP_printk部分定义了打印数据结构的方法。

添加Tracepoint调用

bool blk_update_request(struct request *req, blk_status_t error,unsigned int nr_bytes)
{int total_bytes;trace_block_rq_complete(req, blk_status_to_errno(error), nr_bytes);if (!req->bio)return false;...

Tracepoint数据结构

Tracepoing机制的核心数据为tracepoint和tracepoint_func结构,tracepoint结构对应于一个跟踪点的概念,包含了跟踪点的名称、开关配置以及自定义的回调函数;而tracepoint_func结构描述了开发者注册的回调函数信息。
在这里插入图片描述

TRACE_EVENT实现

TRACE_EVENT宏定义如下:

#define TRACE_EVENT(name, proto, args, struct, assign, print)	\DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
  • name:要创建的跟踪点的名称。
  • prototype:跟踪点回调的原型
  • args:与原型匹配的参数。
  • struct:跟踪程序可以使用(但不需要)存储传递到跟踪点的数据的结构。
  • assign:已类似于 C-like 的方式 将数据分配给结构。
  • print:以可读的ASCII格式输出结构的方法。

DECLARE_TRACE

#define DECLARE_TRACE(name, proto, args)				\__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),		\cpu_online(raw_smp_processor_id()),		\PARAMS(void *__data, proto),			\PARAMS(__data, args))

__DECLARE_TRACE

__DECLARE_TRACE宏定义了一系列内联函数(其中xxx为定义的tracepoint名称):

  • trace_xxx:代码中调用trace_xxx函数记录tracepoint运行信息;
  • register_trace_xxx:向tracepoint注册回调函数,在tracepoint使能时会调用;
  • register_trace_prio_xxx:与register_trace_xxx相似,支持调用优先级;
  • unregister_trace_xxx:向tracepoint去注册回调函数;
  • trace_xxx_enabled:tracepoint使能接口
#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \extern struct tracepoint __tracepoint_##name;			\static inline void trace_##name(proto)		// 定义trace_xxx函数,以上文示例即为trace_block_rq_complete		\{								\if (static_key_false(&__tracepoint_##name.key))		\__DO_TRACE(&__tracepoint_##name,		\TP_PROTO(data_proto),			\TP_ARGS(data_args),			\TP_CONDITION(cond), 0);			\if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) {		\WARN_ON_ONCE(!rcu_is_watching());		\}							\}								\__DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args),		\PARAMS(cond), PARAMS(data_proto), PARAMS(data_args))	\static inline int						\register_trace_##name(void (*probe)(data_proto), void *data)   \   // 定义register_trace_xxx函数,以上文示例即为register_trace_rq_complete{								\return tracepoint_probe_register(&__tracepoint_##name,	\(void *)probe, data);	\}								\static inline int						\register_trace_prio_##name(void (*probe)(data_proto), void *data,\     // 定义register_trace_prio_xxx函数,以上文示例即为register_trace_prio_block_rq_completeint prio)				\{								\return tracepoint_probe_register_prio(&__tracepoint_##name, \(void *)probe, data, prio); \}								\static inline int						\unregister_trace_##name(void (*probe)(data_proto), void *data)     \   //  定义unregister_trace_xxx函数,以上文示例即为unregister_trace_prio_block_rq_complete{								\return tracepoint_probe_unregister(&__tracepoint_##name,\(void *)probe, data);	\}								\static inline void						\check_trace_callback_type_##name(void (*cb)(data_proto))   \   // 定义check_trace_callback_type_xxx函数,以上文示例即为check_trace_callback_type_block_rq_complete{								\}								\static inline bool						\trace_##name##_enabled(void)				\  // 定义trace_xxx_enabled函数,以上文示例即为trace_block_rq_complete_enabled	{								\return static_key_false(&__tracepoint_##name.key);	\}

trace_xxx函数

trace_xxx函数内部主要是调用__DO_TRACE宏来完成实际的跟踪点信息处理,__DO_TRACE的核心流程是遍历tracepoint结构体里面的一个函数数组,执行对应的回调函数,这些回调函数由register_trace_xxx接口进行注册。

#define __DO_TRACE(tp, proto, args, cond, rcuidle)			\do {								\struct tracepoint_func *it_func_ptr;			\void *it_func;						\void *__data;						\int __maybe_unused __idx = 0;				\\if (!(cond))						\return;						\\/* srcu can't be used from NMI */			\WARN_ON_ONCE(rcuidle && in_nmi());			\\/* keep srcu and sched-rcu usage consistent */		\preempt_disable_notrace();				\\/*							\* For rcuidle callers, use srcu since sched-rcu	\* doesn't work from the idle path.			\*/							\if (rcuidle) {						\__idx = srcu_read_lock_notrace(&tracepoint_srcu);\rcu_irq_enter_irqson();				\}							\\it_func_ptr = rcu_dereference_raw((tp)->funcs);		\\if (it_func_ptr) {					\do {						\it_func = (it_func_ptr)->func;		\__data = (it_func_ptr)->data;		\((void(*)(proto))(it_func))(args);	\} while ((++it_func_ptr)->func);		\}							\\if (rcuidle) {						\rcu_irq_exit_irqson();				\srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\}							\\preempt_enable_notrace();				\} while (0)

相关参考

  • Linux tracepoint 简介

相关文章:

浅析Linux追踪技术之ftrace:Tracepoint

文章目录 概述Tracepoint使用定义Tracepoint添加Tracepoint调用 Tracepoint数据结构TRACE_EVENT实现DECLARE_TRACE__DECLARE_TRACE trace_xxx函数相关参考 概述 Tracepoint(跟踪点)是添加到代码流程中的调用点,并且允许开发者注册自定义的回…...

python ftp文件断点续传 并判断ftp文件下载完成

在Python中实现FTP文件的断点续传,通常涉及到以下步骤: 连接到FTP服务器。获取远程文件的大小。检查本地文件是否存在以及它的大小。如果本地文件不存在或大小小于远程文件,从上次中断的位置开始下载。下载完成后,检查文件大小以…...

SpringBoot+Vue3 完成小红书项目

简介 该项目采用微服务架构,实现了前后端分离的系统设计。在前端,我们选择了 Vue3 配合 TypeScript 和 ElementUi 框架,以提升开发效率和用户体验。而在后端,则是运用 SpringBoot 和 Mybatis-plus 进行开发,保证了系统…...

springboot集成Sa-Token及Redis的redisson客户端

文章目录 什么是Sa-Token?为什么集成Redis的redisson客户端?如何集成?maven依赖application.yml配置过滤器配置验证参考什么是Sa-Token? Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权…...

SQL世界之命令语句Ⅴ

目录 一、SQL CREATE INDEX 语句 1.SQL CREATE INDEX 语句 2.SQL CREATE INDEX 语法 3.SQL CREATE UNIQUE INDEX 语法 4.SQL CREATE INDEX 实例 二、SQL 撤销索引、表以及数据库 1.SQL DROP INDEX 语句 2.SQL DROP TABLE 语句 3.SQL DROP DATABASE 语句 4.SQL TRUNCA…...

Springboot拦截器中跨域失效的问题、同一个接口传入参数不同,一个成功,一个有跨域问题、拦截器和@CrossOrigin和@Controller

Springboot拦截器中跨域失效的问题 一、概述 1、具体场景 起因: 同一个接口,传入不同参数进行值的修改时,一个成功,另一个竟然失败,而且是跨域问题拦截器内的request参数调用getHeader方法时,获取不到前端…...

WordPress如何自建txt文本经典语录并随机显示一句话经典语录?

前面跟大家分享的『WordPress集成一言(Hitokoto)API经典语句功能』一文中就提供有自创API,其中懿古今顶部左上角显示的经典语录用的就是自建一个txt文本文件,然后再在前端网页指定位置随机显示语录。具体操作方法如下:…...

Java中JVM常用参数配置(提供配置示例)

目录 前言一、内存参数配置二、垃圾收集器配置三、GC策略配置3.1、基础通用配置3.2、Parallel 和 Parallel Old 常用参数配置3.3、CMS 常用参数配置3.4、G1 常用参数配置 四、GC日志配置五、dump 日志参数配置5.1、OutOfMemory异常时生成dump文件5.2、发生Full GC时生成dump文件…...

图论与图数据应用综述:从基础概念到知识图谱与图智能

目录 前言1 图论基础概念1.1 节点度1.2 度分布1.3 邻接矩阵 2 探索图的高级概念2.1 最短路径的关键性2.2 图的直径与平均路径的意义2.3 循环与路径类型的多样性 3 深入探讨图的广泛应用领域3.1 知识图谱的知识管理3.2 图智能在复杂决策中的应用3.3 图数据挖掘与分析的多领域应用…...

知识碎片-SpringBoot统一返回结果和捕获异常

统一返回结果 定义统一返回结果类ResultResponse定义新注解ResponseResult来标记需要拦截的方法或类添加RestControllerAdvice注解,实现ResponseBodyAdvice接口,重写support, beforeBodyWrite方法 统一结果类ResultResponse Setter Getter public cla…...

Open-FWI代码解析(1)

目录 1. dataset文件 1.1初始化网络 1.2load_every函数 1.3 getitem函数 1.4测试函数 2. transforms文件 2.1裁切函数和翻转函数 2.2上\下采样函数 2.3加入随机因子的上\下采样函数 2.4填充函数 2.5标准图像函数 2.6标准化函数 2.7归一化函数 2.8反归一化 2.9添加噪声的函数 …...

移动机器人激光SLAM导航(五):Cartographer SLAM 篇

参考 Cartographer 官方文档Cartographer 从入门到精通 1. Cartographer 安装 1.1 前置条件 推荐在刚装好的 Ubuntu 16.04 或 Ubuntu 18.04 上进行编译ROS 安装:ROS学习1:ROS概述与环境搭建 1.2 依赖库安装 资源下载完解压并执行以下指令 https://pa…...

第四篇【传奇开心果微博系列】Python微项目技术点案例示例:美女颜值判官

传奇开心果微博系列 系列微博目录Python微项目技术点案例示例系列 微博目录一、微项目目标二、雏形示例代码三、扩展思路四、添加不同类型的美女示例代码五、增加难度等级示例代码六、添加特殊道具示例代码七、设计关卡系统示例代码八、添加音效和背景音乐示例代码九、多人游戏…...

Python学习之路-初识爬虫:requests

Python学习之路-初识爬虫:requests requests的作用 作用:发送网络请求,返回响应数据 中文文档 : http://docs.python-requests.org/zh_CN/latest/index.html 为什么学requests而不是urllib requests的底层实现就是urllibrequests在pytho…...

Linux 常用的命令

① 基本命令 uname -m 显示机器的处理器架构uname -r 显示正在使用的内核版本dmidecode -q 显示硬件系统部件(SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性hdparm -tT /dev/sda 在磁盘上执行测试性读取操作系统信息arch 显示机器的处理器架构uname -m 显示机器的处…...

假期作业 10

1.整理磁盘操作的完整流程,如何接入虚拟机,是否成功识别,对磁盘分区工具的使用,格式化,挂载以及取消挂载 U盘接入虚拟机 在虚拟机--->可移动设备--->找到U盘---->连接 检测U盘是否被虚拟机识别 ls /dev/s…...

【洛谷 P3367】【模板】并查集 题解(并查集+路径压缩)

【模板】并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作。 输入格式 第一行包含两个整数 N , M N,M N,M ,表示共有 N N N 个元素和 M M M 个操作。 接下来 M M M 行,每行包含三个整数 Z i , X i , Y i Z_i,X_i,Y…...

Netty应用(一) 之 NIO概念 基本编程

目录 第一章 概念引入 1.分布式概念引入 第二章 Netty基础 - NIO 1.引言 1.1 什么是Netty? 1.2 为什么要学习Netty? 2.NIO编程 2.1 传统网络通信中开发方式及问题(BIO) 2.1.1 多线程版网络编程 2.1.2 线程池版的网络编程…...

tkinter-TinUI-xml实战(10)展示画廊

tkinter-TinUI-xml实战(10)展示画廊 引言声明文件结构核心代码主界面统一展示控件控件展示界面单一展示已有展示多类展示 最终效果在这里插入图片描述 ![](https://img-blog.csdnimg.cn/direct/286fcaa2fa5648a992a0ac79b4efad82.png) ………… 结语 引言…...

LeetCode二叉树的垂序遍历

题目描述 给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row 1, col - 1) 和 (row 1, col 1) 。树的根结点位于 (0, 0) 。 二叉树的 垂序遍历 从最左边的列开始直到…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

Map相关知识

数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

DiscuzX3.5发帖json api

参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...