Detecção imediata de erros de corrupção de heap no Windows. Como?
Não consigo dormir! :)
Eu tenho um projeto razoavelmente grande no Windows e encontrei alguns problemas de corrupção de heap. Eu li tudo isso, incluindo este bom tópico:Como depurar erros de corrupção de heap?No entanto, nada foi adequado para me ajudar.Debug CRT
eBoundsChecker
Detectou corrupções de heap, mas os endereços eram sempre diferentes e o ponto de detecção estava sempre longe das sobras reais de memória. Eu não dormi até o meio da noite e criei o seguinte hack:
DWORD PageSize = 0;
inline void SetPageSize()
{
if ( !PageSize )
{
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
PageSize = sysInfo.dwPageSize;
}
}
void* operator new (size_t nSize)
{
SetPageSize();
size_t Extra = nSize % PageSize;
nSize = nSize + ( PageSize - Extra );
return Ptr = VirtualAlloc( 0, nSize, MEM_COMMIT, PAGE_READWRITE);
}
void operator delete (void* pPtr)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(pPtr, &mbi, sizeof(mbi));
// leave pages in reserved state, but free the physical memory
VirtualFree(pPtr, 0, MEM_DECOMMIT);
DWORD OldProtect;
// protect the address space, so noone can access those pages
VirtualProtect(pPtr, mbi.RegionSize, PAGE_NOACCESS, &OldProtect);
}
Alguns erros de corrupção de heap se tornaram óbvios e eu consegui corrigi-los. Não houve mais avisos de CRT de depuração na saída. No entanto, tenho algumas perguntas sobre esse hack:
1 Pode produzir falsos positivos?
2 Pode perder algumas das corrupções da pilha? (mesmo se substituirmos malloc / realloc / free?)
3 Falha ao rodar em 32 bits comOUT_OF_MEMORY
, apenas em 64 bits. Estou certo que simplesmente ficamos sem espaço de endereço virtual em 32 bits?