错误中的代码
int main() { void *ptr = 0; int overrun = 1; ptr = malloc(overrun); while(overrun++) { if(!ptr) while(1) Sleep(500); *((char*)ptr + (overrun+1)) = 'a'; printf("\n%d\n",overrun); } return 0; }
从 Visual Studio 2010 的项目菜单中确保构建版本为“Release”和“x64”(机器为 x64)
启用全页堆
gflags /p /enable test.exe /full
将 Windbg 设置为默认调试器
E:\installed\Debugging Tools for Windows (x64)>windbg -I
将代码作为独立于
cmd
的 exe 运行,无需调试器输出:
2 3 4 5 6 7 8 9 10 11 12 13 14
之后,可以看到 Windbg 捕获了损坏。我认为整页堆应该能够立即捕获损坏。
对于为什么整页堆很糟糕有什么评论吗?
最佳答案
由于堆分配需要对齐,因此在发生溢出时无法捕获未跨越对齐边界的溢出,因为内存保护是页粒度的,而不是字节粒度的。这是硬件限制。当您释放内存时,将检测到溢出,并检查尾部字节是否被篡改。
(顺便说一句,说某件事很糟糕会让你被指控的人不太可能费心帮助你解决问题。只是一个提示。)
关于c - 在使用完整页堆的 buf = malloc(1) 后,为什么直到 buf[16] 被覆盖时才抛出保护页异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13313587/