在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
相关产品推荐
相关产品推荐

