static void set_bkpt(struct proc_handle *phdl, uintptr_t addr, u_long *saved) { int error; error = proc_bkptset(phdl, addr, saved); ATF_REQUIRE_EQ_MSG(error, 0, "failed to set breakpoint at 0x%jx", (uintmax_t)addr); }
int t1_bkpt_d() { struct proc_handle *phdl; char *targv[] = { "t1-bkpt-t", NULL}; unsigned long saved; proc_create("./t1-bkpt", targv, NULL, NULL, &phdl); assert(proc_bkptset(phdl, (uintptr_t)t1_bkpt_t, &saved) == 0); proc_continue(phdl); assert(proc_wstatus(phdl) == PS_STOP); proc_bkptexec(phdl, saved); proc_continue(phdl); proc_wstatus(phdl); proc_free(phdl); }
/* * Step over the breakpoint. */ int proc_bkptexec(struct proc_handle *phdl, unsigned long saved) { unsigned long pc; unsigned long samesaved; int status; if (proc_regget(phdl, REG_PC, &pc) < 0) { warn("ERROR: couldn't get PC register"); return (-1); } proc_bkptregadj(&pc); if (proc_bkptdel(phdl, pc, saved) < 0) { warn("ERROR: couldn't delete breakpoint"); return (-1); } /* * Go back in time and step over the new instruction just * set up by proc_bkptdel(). */ proc_regset(phdl, REG_PC, pc); if (ptrace(PT_STEP, proc_getpid(phdl), (caddr_t)1, 0) < 0) { warn("ERROR: ptrace step failed"); return (-1); } proc_wstatus(phdl); status = proc_getwstat(phdl); if (!WIFSTOPPED(status)) { warn("ERROR: don't know why process stopped"); return (-1); } /* * Restore the breakpoint. The saved instruction should be * the same as the one that we were passed in. */ if (proc_bkptset(phdl, pc, &samesaved) < 0) { warn("ERROR: couldn't restore breakpoint"); return (-1); } assert(samesaved == saved); return (0); }