> dr_control_mirror is never supposed to be updated from the target. It's a > one way street - the state we _want_ dr7 to have on next resume. Where is this > 0x400 coming from then? > > Also, what's different in native GDB? This debug registers code is > shared between GDB and GDBserver now. It is read back in win32-i386-low.c::i386_get_thread_context: if (th->tid == current_event->dwThreadId) { /* Copy dr values from the current thread. */ struct x86_debug_reg_state *dr = &debug_reg_state; dr->dr_mirror[0] = th->context.Dr0; dr->dr_mirror[1] = th->context.Dr1; dr->dr_mirror[2] = th->context.Dr2; dr->dr_mirror[3] = th->context.Dr3; dr->dr_status_mirror = th->context.Dr6; dr->dr_control_mirror = th->context.Dr7; } debug_reg_state is a global, which is passed to x86_dr_insert_watchpoint in win32-i386-low.c::i386_insert_point: return x86_dr_insert_watchpoint (&debug_reg_state, hw_type, addr, size); i386_get_thread_context gets called after we receive the watchpoint signal (TARGET_WAITKIND_STOPPED) in win32_wait: case TARGET_WAITKIND_STOPPED: case TARGET_WAITKIND_LOADED: OUTMSG2 (("Child Stopped with signal = %d \n", ourstatus->value.sig)); regcache = get_thread_regcache (current_thread, 1); child_fetch_inferior_registers (regcache, -1); return debug_event_ptid (¤t_event); It looks like just removing the statement that sets dr_control_mirror from the thread's DR7 is sufficient to allow hardware watchpoints to work again. gdb/gdbserver/ChangeLog: * win32-i386-low.c (i386_get_thread_context): Do not set dr->dr_control_mirror. Tested on x86-windows using AdaCore's testsuite. No regression while all watchpoint-related issues get resolved. I admit I could have spent a little more time trying to understand the bigger picture, but I'm a bit under time pressure, so I'm hoping this is enough. Otherwise, I'll look at a better fix. Once we have a fix, I think we'll want it for GDB 7.8.1. I haven't completely checked eitherr, but I think it's there as well. I'll create a PR as soon as I have a minute. Thanks! -- Joel