From 4403d8e9b35649c5b24f65c0ec0decc3839e1164 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Tue, 24 Jan 2012 13:46:55 +0000 Subject: gdb/ Fix watchpoints across inferior fork. * amd64-linux-nat.c (update_debug_registers_callback): Update the comment for linux_nat_iterate_watchpoint_lwps. (amd64_linux_dr_set_control, amd64_linux_dr_set_addr): Use linux_nat_iterate_watchpoint_lwps. (amd64_linux_prepare_to_resume): New comment on Linux kernel. * i386-linux-nat.c (update_debug_registers_callback): Update the comment for linux_nat_iterate_watchpoint_lwps. (i386_linux_dr_set_control, i386_linux_dr_set_addr): Use linux_nat_iterate_watchpoint_lwps. (i386_linux_prepare_to_resume): New comment on Linux kernel. * i386-nat.c: Include inferior.h. (dr_mirror): Remove. (i386_inferior_data, struct i386_inferior_data) (i386_inferior_data_get): New. (i386_debug_reg_state): Use i386_inferior_data_get. (i386_cleanup_dregs, i386_update_inferior_debug_regs) (i386_insert_watchpoint, i386_remove_watchpoint) (i386_stopped_data_address, i386_insert_hw_breakpoint) (i386_remove_hw_breakpoint): New variable state, use i386_debug_reg_state instead of DR_MIRROR. * linux-nat.c (delete_lwp): New declaration. (num_lwps): Move here from downwards. (delete_lwp_cleanup): New. (linux_child_follow_fork): Create new child_lp, call linux_nat_new_thread and linux_nat_prepare_to_resume before calling PTRACE_DETACH. (num_lwps): Move upwards. (linux_nat_iterate_watchpoint_lwps): New. * linux-nat.h (linux_nat_iterate_watchpoint_lwps_ftype): New. (linux_nat_iterate_watchpoint_lwps_ftype): New declaration. gdb/testsuite/ Fix watchpoints across inferior fork. * gdb.threads/watchpoint-fork-child.c: New file. * gdb.threads/watchpoint-fork-mt.c: New file. * gdb.threads/watchpoint-fork-parent.c: New file. * gdb.threads/watchpoint-fork-st.c: New file. * gdb.threads/watchpoint-fork.exp: New file. * gdb.threads/watchpoint-fork.h: New file. --- gdb/amd64-linux-nat.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'gdb/amd64-linux-nat.c') diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index a0bdbd7..f954483 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -336,8 +336,8 @@ amd64_linux_dr_get_status (void) return amd64_linux_dr_get (inferior_ptid, DR_STATUS); } -/* Callback for iterate_over_lwps. Update the debug registers of - LWP. */ +/* Callback for linux_nat_iterate_watchpoint_lwps. Update the debug registers + of LWP. */ static int update_debug_registers_callback (struct lwp_info *lwp, void *arg) @@ -363,9 +363,7 @@ update_debug_registers_callback (struct lwp_info *lwp, void *arg) static void amd64_linux_dr_set_control (unsigned long control) { - ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid)); - - iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL); + linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL); } /* Set address REGNUM (zero based) to ADDR in all LWPs of the current @@ -374,11 +372,9 @@ amd64_linux_dr_set_control (unsigned long control) static void amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr) { - ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid)); - gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR); - iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL); + linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL); } /* Called when resuming a thread. @@ -400,6 +396,13 @@ amd64_linux_prepare_to_resume (struct lwp_info *lwp) struct i386_debug_reg_state *state = i386_debug_reg_state (); 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) { -- cgit v1.1