You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux环境下:内存地址被写入时如何获取堆栈跟踪?

针对x86平台内存写入触发回调的解决方案

1. 手动操作调试寄存器(替代第三方库)

x86架构自带调试寄存器(DR0-DR3存断点地址,DR7存控制规则),直接操作比依赖第三方库更可靠,步骤如下:

  • 把目标地址写入DR0,通过DR7设置写入触发的局部断点(仅当前进程生效)。
  • 注册SIGTRAP信号处理函数,内核触发硬件断点时会发送该信号,在处理函数里调用你的指定逻辑,之后要重置调试寄存器,避免进程卡在断点处。

示例代码片段:

#include <signal.h>
#include <stdio.h>
#include <ucontext.h>

#define TARGET_ADDR 0xdeadbeef // 替换成你的目标地址

void sigtrap_handler(int sig, siginfo_t *info, void *context) {
    ucontext_t *uc = (ucontext_t *)context;
    
    // 这里调用你的自定义函数
    printf("捕获到目标地址写入!地址:%p\n", (void*)TARGET_ADDR);
    
    // 清除DR7的触发标记,让进程继续执行
    uc->uc_mcontext.gregs[REG_DR7] &= ~(0x3 << 0);
}

int main() {
    struct sigaction sa;
    sa.sa_sigaction = sigtrap_handler;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGTRAP, &sa, NULL);

    // 汇编指令设置调试寄存器:DR0存目标地址,DR7开启写入断点
    asm volatile (
        "mov %0, %%dr0\n"
        "mov %%dr7, %%eax\n"
        "or $0x3, %%eax\n" // bit0=1启用DR0,bit1=1设为写入触发
        "mov %%eax, %%dr7\n"
        : : "r"(TARGET_ADDR) : "%eax"
    );

    // 你的业务逻辑代码...
    while(1) {
        sleep(1);
    }

    return 0;
}

2. 用GDB脚本实现自动触发

如果不想修改代码,直接用GDB的硬件断点功能配合自定义命令:

  1. 启动GDB加载程序:gdb ./your_program
  2. 设置写入断点:watch -w *0xdeadbeef(替换成你的目标地址)
  3. 定义断点触发时的执行逻辑:
    define hook-stop
        if $_siginfo.si_signo == SIGTRAP && $_siginfo.si_code == TRAP_HWBKPT
            call your_custom_function() // 调用你的指定函数
            continue // 让程序继续运行
        end
    end
    
  4. 运行程序:run,之后每次目标地址被写入时都会自动执行你的函数。

3. 排查hwbp_lib失效的可能原因

如果坚持用hwbp_lib,先检查这几点:

  • 确认目标地址是当前进程的虚拟地址,不是物理地址或其他进程的地址。
  • 断点类型是否明确设为HWBP_WRITE,而非读或触发类型。
  • 程序是否有足够权限(避免不必要的sudo,部分环境下调试寄存器权限会受限)。
  • 初始化函数hwbp_init()是否返回成功,有没有忽略错误码。

注意事项

  • x86硬件断点最多支持4个,若已有其他断点会导致冲突。
  • 信号处理函数尽量简洁,避免复杂操作,防止死锁或异常。
  • 多线程程序中,调试寄存器是线程私有资源,需要给每个线程都设置断点。

内容的提问来源于stack exchange,提问作者barisdad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:50:33