Skip to main content
Linux 内核提供了多种动态插桩机制,让您无需给内核打补丁或重新编译内核,即可插入探针、收集跟踪信息并测量时序。本页介绍用于代码路径断点的 kprobes、用于函数级性能分析的 ftrace,以及用于调试驱动寄存器访问失败的 MMIO 跟踪。

Kprobes

Kprobes 允许您在任意内核指令地址处设置断点,并在执行到达该点时运行自定义处理程序。该技术是非侵入式的——正在运行的内核不会停止,其他 CPU 会继续执行。

kprobes 的工作原理

  1. 您在某个符号或地址上注册一个探针。
  2. 内核将目标指令替换为一条陷阱指令。
  3. 当陷阱触发时,kprobe 处理程序在与被中断代码相同的上下文中运行。
  4. 内核恢复原始指令并继续执行。
Kprobes 在以下场景特别有用:
  • 跟踪调度器事件(schedule()、try_to_wake_up())
  • 统计某条慢速代码路径被执行的频率
  • 捕获调用参数,而无需添加 printk 并重新构建

Kconfig

在目标设备上验证:

通过 tracefs 使用 kprobe 跟踪事件

使用 kprobes 最简单的方式是通过 tracefs 的 kprobe_events 接口:
如需完整的 kprobes 文档,请参阅 Kernel Probes (kprobes)。

Ftrace

Ftrace 是内核内置的函数跟踪器。它可以记录内核中的每一次函数调用、跟踪特定子系统,或对延迟敏感的代码路径进行性能分析。结果通过 tracefs 接口(/sys/kernel/tracing/)读取。

函数跟踪器

function 跟踪器记录每个被调用的内核函数的名称和所在 CPU:

函数图跟踪器

function_graph 跟踪器记录每个函数的进入和退出,包括执行时间。对于识别慢速代码路径非常有用:
示例输出:

跟踪启动 initcall

在内核命令行中添加以下内容,可在启动时跟踪所有 initcall:
使用以下命令解析结果:
如需完整的 ftrace 文档,请参阅 Function Tracer。

MMIO 跟踪事件

内存映射 I/O(MMIO)跟踪记录内核通过 __raw_{read,write}{b,l,w,q} 访问器执行的每一次寄存器读写。它们对于诊断 Qualcomm® SoC 上以下几类崩溃至关重要: 表:MMIO 崩溃场景

启用 MMIO 跟踪

Kconfig:
在运行时,通过 tracefs 启用 rwmmio 跟踪事件:
示例输出:
每行标明了调用函数(含偏移量)、访问类型(readl/writel/writeq)以及物理地址。将该地址与 SoC 技术参考手册进行交叉比对,即可确定崩溃所涉及的寄存器模块。

崩溃时在控制台转储 MMIO 跟踪

为了在系统崩溃、来不及读取 tracefs 时也能捕获 MMIO 跟踪,可启用将 ftrace 缓冲区转储到控制台的功能:
之后,最后的跟踪条目会包含在串口控制台上的内核 panic 输出中。