Most efficient replacement for IsBadReadPtr?

bool IsBadReadPtr(void* p)
{
    MEMORY_BASIC_INFORMATION mbi = {0};
    if (::VirtualQuery(p, &mbi, sizeof(mbi)))
    {
        DWORD mask = (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY);
        bool b = !(mbi.Protect & mask);
        // check the page is not a guard page
        if (mbi.Protect & (PAGE_GUARD|PAGE_NOACCESS)) b = true;

        return b;
    }
    return true;
}

a thread-safe solution would be nice

I'm guessing it's only IsBadWritePtr that isn't thread-safe.

just doing a memcpy inside an exception handler

This is effectively what IsBadReadPtr is doing ... and if you did it in your code, then your code would have the same bug as the IsBadReadPtr implementation: http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx

--Edit:--

The only problem with IsBadReadPtr that I've read about is that the bad pointer might be pointing to (and so you might accidentally touch) a stack's guard page. Perhaps you could avoid this problem (and therefore use IsBadReadPtr safely), by:

  • Know what threads are running in your process
  • Know where the threads' stacks are, and how big they are
  • Walk down each stack, delberately touching each page of the stack at least once, before you begin to call isBadReadPtr

Also, the some of the comments associated with the URL above also suggest using VirtualQuery.