Linux内核中通过perf_event监控内存访问的硬件断点触发流程

以下是Linux内核中通过perf_event监控内存访问的硬件断点触发流程分析,从core.c的入口函数开始:

 

1. 核心触发路径(kernel/events/core.c)

perf_event_create_kernel_counter()

  └─ perf_event_alloc()

      └─ hw_breakpoint_alloc() # 分配硬件断点资源

  └─ perf_install_in_context() # 将事件绑定到CPU上下文

      └─ event_sched_in() # 事件激活

          └─ hw_breakpoint_add() # 实际写入CPU调试寄存器

2. 内存访问监控关键函数

(1) 断点属性配置

在perf_event_attr中指定监控类型:

 

struct perf_event_attr attr = {

    .type = PERF_TYPE_BREAKPOINT,

    .bp_type = HW_BREAKPOINT_RW, // 读写监控

    // 或 HW_BREAKPOINT_W (仅写), HW_BREAKPOINT_R (仅读)

    .bp_addr = (unsigned long)&target_var, // 监控地址

    .bp_len = sizeof(long), // 监控长度(需对齐)

};

(2) 事件激活入口

核心函数:event_sched_in()

位置:kernel/events/core.c

 

static void event_sched_in(struct perf_event *event, ...) {

    if (event->pmu->event_idx == PERF_TYPE_BREAKPOINT)

        hw_breakpoint_add(event); // 调用架构特定安装函数

}

3. 硬件断点触发流程

(1) CPU异常产生

当监控的内存地址被访问时:

 

CPU生成#DB异常(x86)或Debug Exception(ARM)

跳转到架构相关异常处理程序:

x86: do_debug() (arch/x86/kernel/traps.c)

ARM: do_DataAbort() (arch/arm/mm/fault.c)

(2) 事件回调触发

核心函数链:

 

arch_trigger_dpft_handler() // 架构相关处理

  └─ perf_bp_event() // kernel/events/core.c

      ├─ perf_sample_data_init(&sample, bp->attr.bp_addr) // 记录断点地址

      └─ perf_event_overflow(bp, &sample, regs) // 触发事件处理

          ├─ 用户态:通过perf环形缓冲区通知

          └─ 内核态:直接调用overflow_handler回调

 

4. 关键代码片段(core.c)

(1) 事件溢出处理

// kernel/events/core.c

void perf_event_overflow(struct perf_event *event, ...) {

    if (event->overflow_handler)

        event->overflow_handler(event, data, regs); // 直接回调

    else

        __perf_event_overflow(event, ...); // 用户态通知

}

(2) 断点事件采样

static void perf_bp_event(struct perf_event *bp, void *data) {

    struct perf_sample_data sample;

    perf_sample_data_init(&sample, bp->attr.bp_addr); // 记录被访问地址

    perf_event_overflow(bp, &sample, regs);

}

5. 监控数据流

内存访问 → CPU调试异常 → 内核异常处理 → perf_bp_event() → 

   ├─ 用户态:perf_event_output() → 环形缓冲区 → read(fd)

   └─ 内核态:直接调用overflow_handler

6. 调试验证方法

查看已注册断点:

cat /sys/kernel/debug/tracing/events/breakpoints/breakpoint/format

动态追踪触发:

perf probe -a 'perf_bp_event'

echo 1 > /sys/kernel/debug/tracing/events/probe/perf_bp_event/enable

关键结论

起始点:监控流程从event_sched_in()调用hw_breakpoint_add()开始激活硬件断点

触发点:实际内存访问通过CPU异常触发perf_bp_event()回调

数据记录:被访问地址通过perf_sample_data_init()保存在采样数据中

该机制广泛用于内核调试工具(如perf mem)和安全监控场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值