When aidbg (x64) debugs a 32-bit target under WoW64, software breakpoints
(int3) surface as STATUS_WX86_BREAKPOINT (0x4000001f) instead of
STATUS_BREAKPOINT (0x80000003), and the step-over single step as
STATUS_WX86_SINGLE_STEP (0x4000001e). Route both to the existing
breakpoint/single-step handling so breakpoints are consumed and restored
correctly; otherwise continue re-stops on the same address forever.
Two fixes from PR review of the thread-exit reset-recovery:
- When restoring the hardware breakpoint after the stepped-over thread exits, rebuild
each still-suspended thread's debug registers from the authoritative DebugRegister[]
table (re-arming every enabled slot, as CREATE_THREAD does) instead of from the
exiting thread's now-gone context. The old code rebuilt DR7 from GetContextData()
(the dead thread), writing a DR7 with only the restored slot to every thread and
silently disabling any other hardware breakpoint. The restore is also moved before
the threads are resumed, since SetThreadContext does not reliably update the debug
registers of a running thread.
- Erase the per-thread single-step state in the EXIT_THREAD handler. A thread can exit
after StepInto() armed its step but before the trap event arrives; leaving the entry
behind means a reused thread id inherits it (StepInto declines to arm, or a later
single-step fires the dead thread's callback).
If a thread is terminated (e.g. by ExitProcess) while it is in the middle of a
breakpoint step-over - its breakpoint temporarily removed and a restore pending on
its next single-step - the EXIT_THREAD handler cleared ThreadBeingProcessed but left
the reset state (ResetBPX/ResetHwBPX/ResetMemBPX) armed and the breakpoint removed.
The next thread's event then consumed that orphaned reset and was misinterpreted as a
step-over reset, producing a stray single-step that was passed to the debuggee
unhandled and crashed it. This was most visible with hardware breakpoints under
multi-thread contention. Complete the pending restore when the thread-being-processed
exits.
- Replaced the implicit bit-shift logic with an explicit mapping
to prevent the OS from silently duplicating pages via Copy-on-Write.
- Added explicit cases for PAGE_WRITECOPY and PAGE_EXECUTE_WRITECOPY.