费解的NTDLL断点(转载)

来源:互联网 发布:thinkphp b2b源码 编辑:程序博客网 时间:2024/06/10 09:46
 

费解的NTDLL断点
(from http://blog.vckbase.com/hyj/archive/2006/06/28/21006.html)

我们在调试程序(F5)的过程中,有时会突然的显示一个对话框,上面显示这样一条信息:
User breakpoint called from code at 0x77fa018c
或者是
Unhandled exception at 0x77f767cd (ntdll.dll) in myapp.exe: User breakpoint.接着你就没有进一步往下执行了。

你会发现在你点了这个对话框的确定按钮之后,会在Output窗口中发现多了一行信息:
HEAP[DebugInfo2.exe]: Heap block at 00030FD8 modified at 00031010 past requested size of 30

查看堆栈窗口,里面显示这样的信息:
NTDLL! 7c921230()
NTDLL! 7c97db9c()
NTDLL! 7c98cd11()
NTDLL! 7c980af8()
KERNEL32! 7c85e7af()
_CrtIsValidHeapPointer(const void * 0x00031000) line 1697
_free_dbg(void * 0x00031000, int 0x00000001) line 1044 + 9 bytes
operator delete(void * 0x00031000) line 49 + 16 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f15, int 0x00000001) line 13 + 15 bytes
WinMainCRTStartup() line 198 + 54 bytes
KERNEL32! 7c816d4f()

重现这样的现场很容易的,只需几行代码就可以了
char *p = new char[4];
lstrcpy(p, "this is a test");
delete p;

为什么会有这样的信息消息框出现呢?这是因为如果我们在调试状态下,操作系统用DebugWin32Heap来替代正常的heap分配内存空间。在这个堆上的任何操作,debug的堆管理器会检查堆的数据完整性,如果它发现了一个错误,就会报告一个消息上来。
用BoundsChecker做运行期的检查可以查到这个错误的原因,不过我们有更好的选择,那就是windows 2000 SP2之后提供的PageHeap机制。
修改一下注册表就可以开启了:
HKLM/Software/Microsoft/Windows NT/CurrentVersion/Image File Execution Options/yourapp.exe
    GlobalFlag = REG_DWORD 0x2000000
    PageHeapFlags = REG_DWORD 0x3

原创粉丝点击