static void amd64_linux_new_fork (struct lwp_info *parent, pid_t child_pid) { pid_t parent_pid; struct i386_debug_reg_state *parent_state; struct i386_debug_reg_state *child_state; /* NULL means no watchpoint has ever been set in the parent. In that case, there's nothing to do. */ if (parent->arch_private == NULL) return; /* Linux kernel before 2.6.33 commit 72f674d203cd230426437cdcf7dd6f681dad8b0d will inherit hardware debug registers from parent on fork/vfork/clone. Newer Linux kernels create such tasks with zeroed debug registers. GDB core assumes the child inherits the watchpoints/hw breakpoints of the parent, and will remove them all from the forked off process. Copy the debug registers mirrors into the new process so that all breakpoints and watchpoints can be removed together. The debug registers mirror will become zeroed in the end before detaching the forked off process, thus making this compatible with older Linux kernels too. */ parent_pid = ptid_get_pid (parent->ptid); parent_state = i386_debug_reg_state (parent_pid); child_state = i386_debug_reg_state (child_pid); *child_state = *parent_state; }
static void amd64_linux_prepare_to_resume (struct lwp_info *lwp) { int clear_status = 0; /* NULL means this is the main thread still going through the shell, or, no watchpoint has been set yet. In that case, there's nothing to do. */ if (lwp->arch_private == NULL) return; if (lwp->arch_private->debug_registers_changed) { struct i386_debug_reg_state *state = i386_debug_reg_state (ptid_get_pid (lwp->ptid)); int i; /* On Linux kernel before 2.6.33 commit 72f674d203cd230426437cdcf7dd6f681dad8b0d if you enable a breakpoint by the DR_CONTROL bits you need to have already written the corresponding DR_FIRSTADDR...DR_LASTADDR registers. Ensure DR_CONTROL gets written as the very last register here. */ for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) if (state->dr_ref_count[i] > 0) { amd64_linux_dr_set (lwp->ptid, i, state->dr_mirror[i]); /* If we're setting a watchpoint, any change the inferior had done itself to the debug registers needs to be discarded, otherwise, i386_stopped_data_address can get confused. */ clear_status = 1; } amd64_linux_dr_set (lwp->ptid, DR_CONTROL, state->dr_control_mirror); lwp->arch_private->debug_registers_changed = 0; } if (clear_status || lwp->stopped_by_watchpoint) amd64_linux_dr_set (lwp->ptid, DR_STATUS, 0); }
static void i386_linux_prepare_to_resume (struct lwp_info *lwp) { int clear_status = 0; /* NULL means this is the main thread still going through the shell, or, no watchpoint has been set yet. In that case, there's nothing to do. */ if (lwp->arch_private == NULL) return; if (lwp->arch_private->debug_registers_changed) { struct i386_debug_reg_state *state = i386_debug_reg_state (ptid_get_pid (lwp->ptid)); int i; /* See amd64_linux_prepare_to_resume for Linux kernel note on i386_linux_dr_set calls ordering. */ i386_linux_dr_set (lwp->ptid, DR_CONTROL, 0); for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++) if (state->dr_ref_count[i] > 0) { i386_linux_dr_set (lwp->ptid, i, state->dr_mirror[i]); /* If we're setting a watchpoint, any change the inferior had done itself to the debug registers needs to be discarded, otherwise, i386_stopped_data_address can get confused. */ clear_status = 1; } if (state->dr_control_mirror != 0) i386_linux_dr_set (lwp->ptid, DR_CONTROL, state->dr_control_mirror); lwp->arch_private->debug_registers_changed = 0; } if (clear_status || lwp->stopped_by_watchpoint) i386_linux_dr_set (lwp->ptid, DR_STATUS, 0); }