| [轉載]不要放過(guò)User breakpoint called from code at [0x77000000] |
| 摘自:http://blog.csdn.net/m_star_jy_sy/archive/2009/08/12/4438662.aspx VC調試程序時(shí),程序報出“User breakpoint called from code at 0x77000000[程序地址]”對話(huà)框。從表面上看,這好像是用戶(hù)設置斷點(diǎn)引起的錯誤。這樣的對話(huà)框很容易誤導程序員,認為是個(gè)斷點(diǎn)提示,所以也就沒(méi) 去管它。但是找遍了源代碼也沒(méi)有發(fā)現哪里有設置斷點(diǎn),這很奇怪。而且這個(gè)對話(huà)框每次必報。上網(wǎng)查找才發(fā)現這個(gè)問(wèn)題原來(lái)是程序堆內存被破壞導致的。至于為啥 報用戶(hù)斷點(diǎn)這個(gè)對話(huà)框不理解。 這種問(wèn)題通常是程序堆內存被破壞。程序報出這樣的對話(huà)框有時(shí)不會(huì )對整個(gè)程序造成破壞,依然能夠繼續運行,但千萬(wàn)不要放過(guò),像這種破壞堆內存的隱藏 BUG,有可能造成整個(gè)軟件的crash。若是release版本也許什么提示都沒(méi)有,這是因為在debug下,操作系統用DebugWin32Heap 來(lái)代替正常的heap分配內存空間。在這個(gè)堆上的任何操作,debug的堆管理器會(huì )檢查堆的數據完整性,如果它發(fā)現了一個(gè)錯誤,就會(huì )報告一個(gè)消息上來(lái)。 既然是delete的時(shí)候出了問(wèn)題,那就是這個(gè)程序很可能去訪(fǎng)問(wèn)了“非法”的內存,非法內存是指不是由你的程序分配的內存塊,但是被你的程序在某種情況下 訪(fǎng)問(wèn)到了,當然這是堆上的情況,所以在release下可能一時(shí)不會(huì )出問(wèn)題。程序在堆上分配了那么多對象,到底哪次分配出了問(wèn)題?這還是很難定位到錯誤, 用BoundsChecker完整跑一遍是一個(gè)好辦法,但是比較麻煩。試想如果在每次分配的內存塊邊界做限制,設置為虛擬內存,也就是 NO_ACCESS(不可訪(fǎng)問(wèn)),那程序試圖讀寫(xiě)這個(gè)地方的時(shí)候,就會(huì )出錯,程序會(huì )馬上斷下來(lái),也就是所謂的PageHeap機制。 微軟提供了PageHeap機制來(lái)方便程序員查找堆破壞問(wèn)題。 要讓程序啟用Full Page Heap機制,有2種方法。 1.直接修改注冊表 exe: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\appName.exe下增加如下設置, 屬性名:GlobalFlag,字符串類(lèi)型,值:x02200000 屬性名:PageHeapFlags,字符串類(lèi)型,值:0x3 屬性名:VerifierFlags,DWORD類(lèi)型,值:1 其中appName.exe為你正在調試的程序文件名(不需要路徑) dll: GlobalFlag,字符串類(lèi)型,值是0x02000000 PageHeapTargetDlls,字符串類(lèi)型,值是調試的dll名稱(chēng),不帶路徑 VerifierFlags,DWORD類(lèi)型,值是00000001 PageHeapFlags,字符串類(lèi)型,0x403 注冊表的子健值應該是dll依附的exe程序名。 2.使用Debugging Tools for Windows[http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx] exe: 運行 gflags –p /enable appName.exe /full 即可自動(dòng)幫你添加上述注冊表值。 gflags在Debugging Tools for Windows的安裝目錄下 dll: gflags –p /enable appName.exe /full /dlls dllName.dll 再次debug下調試程序,User breakpoint called from code at不會(huì )再出現了,而出現的是未處理的異常對話(huà)框,且程序斷在了出錯的地方。 |
聯(lián)系客服