unexpected user breakpoint in ntdll.dll

今天解決了一個困擾的很久的問題,debug狀態下進程退出的時候總是出現一個莫名其妙的中斷,看調用堆棧似乎是一個CALSS析構的時候釋放內存出問題了,F5後可以繼續退出,由於沒有直接影響到用戶的使用,就一直沒有解決這個問題,今天有時間,搜了些資料,終於找到了一篇有價值的資料,按照說明設置好了環境一下就定位到出問題的點了,原因是程序退出的時候調用了一個appAuto->Revoke(); 該函數內部將appAuto對象給銷燬了,之後又調用了appAuto->setClosing(true);,就導致了開始說的問題。

 

unexpected user breakpoint in ntdll.dll

 

Updated: 01.09.2005

We were in the middle of the debugging session, when suddenly the debugger displayed a message similar to the following:

User breakpoint called from code at 0x77fa018c

or the following:

Unhandled exception at 0x77f767cd (ntdll.dll) in myapp.exe: User breakpoint.

What happened? We did not even set any breakpoints, so why there is a user breakpoint? The problem starts looking even stranger when we notice that the application works fine when we start it outside of the debugger! But under debugger it keeps showing the message about user breakpoint, so that we cannot effectively debug our application anymore.

Searching for an answer, we look at Debug Output window. And yes, there is another message! For example:

HEAP[myapp.exe]: Heap block at 00360F78 modified at 00360F90 past requested size of 10

Aha, it looks like the heap is corrupted. The contents of Call Stack window also point to the heap:

NTDLL! DbgBreakPoint@0 address 0x77fa018c
NTDLL! RtlpBreakPointHeap@4 + 38 bytes
NTDLL! RtlpCheckBusyBlockTail@4 + 106 bytes
NTDLL! RtlpValidateHeapEntry@12 + 146975 bytes
NTDLL! RtlDebugFreeHeap@12 + 191 bytes
NTDLL! RtlFreeHeapSlowly@12 + 70765 bytes
NTDLL! RtlFreeHeap@12 + 4078 bytes
MYAPP! free + 102 bytes
MYAPP! operator delete(void *) + 9 bytes
main(int 1, char * * 0x003610b0) line 21 + 15 bytes
MYAPP! mainCRTStartup + 180 bytes
KERNEL32! BaseProcessStart@4 + 130958 bytes

It turns out that when we start the application under debugger, the operating system uses a special kind of heap – Debug Win32 heap – instead of the normal heap. Whenever an operation on the heap is performed (such as allocating or freeing memory), the debug heap manager checks integrity of the heap entries and internal structures. If it founds a corruption, it notifies us via a hard-coded breakpoint, which is reported by the debugger.

How can we find the reason of the heap corruption? We can of course employ a specialized runtime checker application (such as BoundsChecker, Purify or Memory Validator), but I prefer to use PageHeap, because it is part of the operating system (since Windows 2000 SP2) and is easy to use. Detailed technical information about PageHeap can be found in KB286470.

We can enable Full PageHeap with the help of the following Registry entries:

HKLM/Software/Microsoft/Windows NT/CurrentVersion/Image File Execution Options/yourapp.exe
    GlobalFlag = REG_DWORD 0x2000000
    PageHeapFlags = REG_DWORD 0x3

(replace yourapp.exe with the real name of your executable)

If you have Debugging Tools for Windows installed, there is another way to achieve the same – run the following command:

gflags –p /enable yourapp.exe /full

(gflags.exe can be found in the installation directory of Debugging Tools)

After we have enabled Full PageHeap, we should run the application under debugger and wait for access violations or hard-coded breakpoints. After an access violation occurred or a breakpoint has been hit, examination of the current source line and the call stack usually allows us to immediately see who is corrupting the heap.

Note also that it is recommended to link the application with release version of CRT library (that is, use /ML, /MT or /MD compiler option (or the corresponding IDE equivalent) instead of /MLd, /MTd or /MDd option). This is because debug version of CRT library uses its own heap checking infrastructure (by the way, not as powerful as Full PageHeap), which can overlap with PageHeap and hide some errors instead of exposing them.

Another situation that worth talking about is when we are debugging a DLL that is loaded by a large application (often a 3rd party application). Since there is probably no point in checking the whole application with PageHeap, we can ask it to check only the heap entries that are allocated by our DLL:

gflags –p /enable yourapp.exe /full /dlls yourdll.dll
原文地址:http://www.debuginfo.com/tips/userbpntdll.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章