diff options
author | Tom Tromey <tromey@adacore.com> | 2020-04-24 06:48:01 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2020-04-24 06:48:01 -0600 |
commit | 7be2bb4f47b7b25d4f60b52f6ebaade0644827f2 (patch) | |
tree | 193917cb4296ca3d8a8a65aafc570768398a4972 /gdb | |
parent | 884287754e8da49581b4873b936d8eba7b1f052e (diff) | |
download | gdb-7be2bb4f47b7b25d4f60b52f6ebaade0644827f2.zip gdb-7be2bb4f47b7b25d4f60b52f6ebaade0644827f2.tar.gz gdb-7be2bb4f47b7b25d4f60b52f6ebaade0644827f2.tar.bz2 |
Fix Windows debugging regression
The updated pending stop series introduced a regression in Windows
debugging. When stopped at a software breakpoint, we would adjust the
PC each time it was requested -- however, more than a single
adjustment is incorrect. This patch introduces a new flag that is
used to ensure the adjustment only happens a single time.
No similar change is needed in gdbserver, because it adjusts the PC in
a different way.
I still can't run the gdb test suite on Windows, but I can run the
internal AdaCore test suite there; and this fixes the regressions
there.
gdb/ChangeLog
2020-04-24 Tom Tromey <tromey@adacore.com>
* nat/windows-nat.h (struct windows_thread_info)
<pc_adjusted>: New member.
* windows-nat.c (windows_fetch_one_register): Check
pc_adjusted.
(windows_nat_target::get_windows_debug_event)
(windows_nat_target::wait): Set pc_adjusted.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/nat/windows-nat.h | 5 | ||||
-rw-r--r-- | gdb/windows-nat.c | 10 |
3 files changed, 23 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c2dc2b6..102edfc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2020-04-24 Tom Tromey <tromey@adacore.com> + + * nat/windows-nat.h (struct windows_thread_info) + <pc_adjusted>: New member. + * windows-nat.c (windows_fetch_one_register): Check + pc_adjusted. + (windows_nat_target::get_windows_debug_event) + (windows_nat_target::wait): Set pc_adjusted. + 2020-04-24 Tom de Vries <tdevries@suse.de> * contrib/cc-with-tweaks.sh: Remove <exec>.gdb-index file handling. diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h index 8d0fa9b..80c652b 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -93,6 +93,11 @@ struct windows_thread_info breakpoint. This is used to offset the PC when needed. */ bool stopped_at_software_breakpoint = false; + /* True if we've adjusted the PC after hitting a software + breakpoint, false otherwise. This lets us avoid multiple + adjustments if the registers are read multiple times. */ + bool pc_adjusted = false; + /* The name of the thread, allocated by xmalloc. */ gdb::unique_xmalloc_ptr<char> name; }; diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index b857f82..f52af9a 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -604,6 +604,7 @@ windows_fetch_one_register (struct regcache *regcache, else { if (th->stopped_at_software_breakpoint + && !th->pc_adjusted && r == gdbarch_pc_regnum (gdbarch)) { int size = register_size (gdbarch, r); @@ -622,6 +623,8 @@ windows_fetch_one_register (struct regcache *regcache, value -= gdbarch_decr_pc_after_break (gdbarch); memcpy (context_offset, &value, size); } + /* Make sure we only rewrite the PC a single time. */ + th->pc_adjusted = true; } regcache->raw_supply (r, context_offset); } @@ -1757,6 +1760,7 @@ windows_nat_target::get_windows_debug_event (int pid, ptid_t ptid = ptid_t (current_event.dwProcessId, thread_id, 0); th = thread_rec (ptid, INVALIDATE_CONTEXT); th->stopped_at_software_breakpoint = true; + th->pc_adjusted = false; } pending_stops.push_back ({thread_id, *ourstatus, current_event}); thread_id = 0; @@ -1835,7 +1839,11 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, || (current_event.u.Exception.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT)) && windows_initialization_done) - current_windows_thread->stopped_at_software_breakpoint = true; + { + current_windows_thread->stopped_at_software_breakpoint + = true; + current_windows_thread->pc_adjusted = false; + } } return result; |