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

在C语言中为Linux进程集成ARM64硬件Watchpoint的疑问及代码正确性验证请求

在C语言中为Linux进程集成ARM64硬件Watchpoint的疑问及代码正确性验证请求

我正在研究Linux的断点测试用例,想弄明白它的原理后集成到一个Linux进程中。

我对下面这个函数不太理解:

static bool set_watchpoint(pid_t pid, int size, int wp)
{
    const volatile uint8_t *addr = &var[32 + wp];
    const int offset = (uintptr_t)addr % 8;
    const unsigned int byte_mask = ((1 << size) - 1) << offset;
    const unsigned int type = 2; /* Write */
    const unsigned int enable = 1;
    const unsigned int control = byte_mask << 5 | type << 3 | enable;
    struct user_hwdebug_state dreg_state;
    struct iovec iov;

    memset(&dreg_state, 0, sizeof(dreg_state));
    dreg_state.dbg_regs[0].addr = (uintptr_t)(addr - offset);
    dreg_state.dbg_regs[0].ctrl = control;
    iov.iov_base = &dreg_state;
    iov.iov_len = offsetof(struct user_hwdebug_state, dbg_regs) + sizeof(dreg_state.dbg_regs[0]);
    if (ptrace(PTRACE_SETREGSET, pid, NT_ARM_HW_WATCH, &iov) == 0)
        return true;

    if (errno == EIO)
        ksft_print_msg("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) not supported on this hardware: %s\n", strerror(errno));

    ksft_print_msg("ptrace(PTRACE_SETREGSET, NT_ARM_HW_WATCH) failed: %s\n",strerror(errno));

    return false;
}

我有个疑问:dreg_state.dbg_regs[0].addr = (uintptr_t)(addr - offset); 这行代码设置的是不是Watchpoint要监控的目标地址?

下面是我自己写的代码(是我对用法的理解和尝试),如果有错误的话请帮忙纠正:

#include <sys/uio.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <asm/ptrace.h>

void ptrace_WP_set(pid_t child, uintptr_t address, size_t size) {
    const unsigned byte_mask = (1 << size) - 1;
    const unsigned type = 2; // Write.
    const unsigned enable = 1;
    const unsigned control = byte_mask << 5 | type << 3 | enable;

    struct user_hwdebug_state dreg_state;
    memset(&dreg_state, 0, sizeof dreg_state);
    dreg_state.dbg_regs[0].addr = address;
    dreg_state.dbg_regs[0].ctrl = control;
    struct iovec iov;
    iov.iov_base = &dreg_state;
    iov.iov_len = offsetof(struct user_hwdebug_state, dbg_regs) + sizeof(dreg_state.dbg_regs[0]);
    ptrace(PTRACE_SETREGSET, child, NT_ARM_HW_WATCH, &iov);
}

void run_WP (uintptr_t address){
    pid_t child = fork();
    int status;
    siginfo_t siginfo;

    if (child == 0) {
    
        //set so that parent can trace the children
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    
        //stop
        raise(SIGSTOP);
      
        //continue to return to main
        return;
    } else {
        
    }

    //wait for child and parent to be ready ?
    waitpid(pid, &status, __WALL);

    //set the watchpoint
    ptrace_WP_set(child, address, 16);
    
    //continue, as we stop the pid above with raise(SIGSTOP)
    ptrace(PTRACE_CONT, pid, NULL, NULL);

    //wait for child and parent to hit the break point ?
    waitpid(pid, &status, __WALL);

    //get the breakpoint info
    ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);

    //kill the parent ?
    kill(pid, SIGKILL);

    //wait for parent to be kill ?
    waitpid(pid, &status, 0);
}

void main () {

    int a = 0;

    run_WP(&a);

    a = 3; //trigger the watchpoint ?
}

非常感谢各位的帮助!


备注:内容来源于stack exchange,提问作者Henry Leong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 02:55:32