Bug
MemoryReadSafe hangs forever when a debugger pauses in the UE_CH_ACCESSVIOLATION / UE_CH_PAGEGUARD callback (second-chance exception) and then reads the target's memory.
Repro
With aidbg (a TitanEngine-based debugger) debugging a 64-bit program that raises a write-AV:
aidbg --batch -x "file test_exception.exe" -ex "set args av" -ex "run" -ex "dump 0x140000000 16"
The session stops at 0xc0000005, then dump (which calls MemoryReadSafe) never returns and the debugger hangs. bt still works (it does not use MemoryReadSafe). The same happens on a 32-bit (WoW64) target calling through a null function pointer.
Root cause
DebugLoop() holds LockBreakPointBuffer (via breakpointLock) for the whole STATUS_GUARD_PAGE_VIOLATION / STATUS_ACCESS_VIOLATION case. For a debuggee-generated AV (no memory breakpoint) DBGCode stays DBG_EXCEPTION_NOT_HANDLED and chAccessViolation is invoked inside that lock scope. A debugger that blocks in the callback leaves the lock held, so the next MemoryReadSafe (→ BreakPointPostReadFilter, same lock) deadlocks.
Suggested fix
Release breakpointLock before invoking the AV/GUARD_PAGE handler, mirroring the existing unlock() before the memory-breakpoint callback.
Bug
MemoryReadSafehangs forever when a debugger pauses in theUE_CH_ACCESSVIOLATION/UE_CH_PAGEGUARDcallback (second-chance exception) and then reads the target's memory.Repro
With
aidbg(a TitanEngine-based debugger) debugging a 64-bit program that raises a write-AV:The session stops at
0xc0000005, thendump(which callsMemoryReadSafe) never returns and the debugger hangs.btstill works (it does not useMemoryReadSafe). The same happens on a 32-bit (WoW64) target calling through a null function pointer.Root cause
DebugLoop()holdsLockBreakPointBuffer(viabreakpointLock) for the wholeSTATUS_GUARD_PAGE_VIOLATION/STATUS_ACCESS_VIOLATIONcase. For a debuggee-generated AV (no memory breakpoint)DBGCodestaysDBG_EXCEPTION_NOT_HANDLEDandchAccessViolationis invoked inside that lock scope. A debugger that blocks in the callback leaves the lock held, so the nextMemoryReadSafe(→BreakPointPostReadFilter, same lock) deadlocks.Suggested fix
Release
breakpointLockbefore invoking the AV/GUARD_PAGE handler, mirroring the existingunlock()before the memory-breakpoint callback.