winapivisual-c++

IsBadReadPtr Exception access violation reading location only when debugger is attached


This test throws an exception with debugger attached:

SECTION("IsBadReadPtr") {
    auto AllocatedAddress = VirtualAlloc(nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_NOACCESS);
    IsBadReadPtr(AllocatedAddress, 0x1000);
}

enter image description here

Without the debugger attached it works in debug and release builds. The function IsBadReadPtr is supposed to check if the pointer is accessible.

Any way to fix that? I can't debug other tests and my code when this type of tests throws the exception.


Solution

  • Clearly IsBadReadPtr() is triggering an Access Violation error by reading an inaccessible page. The Access Violation is handled internally by IsBadReadPtr() so it can return TRUE.

    Raymond Chen states as much on his blog:

    IsBadXxxPtr should really be called CrashProgramRandomly

    Alternatively, it’s possible that your function was called by some code that intentionally passed a pointer to a guard page (or a PAGE_NOACCESS page) and was expecting to receive that guard page exception or access violation exception so that it could dynamically generate the data that should go onto that page. (Simulation of large address spaces via pointer-swizzling is one scenario where this can happen.) Swallowing the exception in IsBadXxxPtr means that the caller’s exception handler doesn’t get a chance to run, which means that your code rejected a pointer that would actually have been okay, if only you had let the exception handler do its thing.

    That means the Access Violation has to occur before it can be swallowed. You are simply seeing the debugger reporting the Access Violation to you before IsBadReadPtr() sees it.

    This is normal behavior for a debugger!

    Simply continue execution and the debugger will pass the Access Violation back to the program's code for normal handling. IsBadReadPtr() will then catch the Access Violation and move on.

    This is expected behavior. There is nothing to fix, as it is not broken.

    If you don't want the debugger to report this Access Violation, then you will just have to configure the debugger to ignore it. Unfortunately, Visual C++'s debugger is not flexible enough to ignore the exception only in this one section of code. Some other debuggers are more flexible and can do that.