[c++] Heisenbug:WinApi程序在某些電腦上崩潰


Answers

4)寫一個日誌表明崩潰發生在一個本地int變量的聲明上! 那怎麼可能? 內存損壞?

可執行文件/程序集中的底層代碼是什麼? int的聲明完全不是代碼,因此不會崩潰。 你以某種方式初始化int嗎?

要查看發生崩潰的代碼,您應該執行所謂的事後分析。

Windows錯誤報告

如果你想分析崩潰,你應該得到一個崩潰轉儲。 一個選項是註冊Windows錯誤報告 - 需要一些錢(你需要一個數字代碼簽名ID)和一些表格填寫。 有關更多信息,請訪問https://winqual.microsoft.com/

直接從客戶處獲取用於WER的故障轉儲

另一個選擇是與遇到碰撞的某個用戶聯繫,並直接從他那裡獲取用於WER的故障轉儲。 用戶可以在向Microsoft發送崩潰之前單擊“技術詳細信息”時執行此操作 - 可以在此檢查崩潰轉儲文件的位置。

你自己的小轉儲

另一個選擇是註冊你自己的異常處理程序,處理異常並在你想要的地方寫一個小型轉儲程序。 詳細描述可以在Code Project Post-Mortem使用Minidumps和Visual Studio .NET文章調試您的應用程序中找到。

Question

請幫忙! 我真的在我的智慧結束。 我的程序是一個小小的個人筆記管理器(谷歌“cintanotes”)。 在某些計算機上(當然,我也沒有)在啟動之後,它會崩潰,出現未處理的異常。 這些電腦沒什麼特別的可以說,只是他們往往有AMD CPU。

環境:Windows XP,Visual C ++ 2005/2008,原始WinApi。

以下是關於這個“Heisenbug”的確定:

1)崩潰只發生在版本。

2)一旦我刪除所有GDI相關的東西,崩潰就消失了。

3)BoundChecker沒有抱怨。

4)寫一個日誌表明崩潰發生在一個本地int變量的聲明上! 那怎麼可能? 內存損壞?

任何想法將不勝感激!

更新:我已經設法讓應用程序在“錯誤”的PC上調試。 結果:

“在CintaNotes.exe 0x0044a26a未處理的異常:0xC000001D:非法指令”。

和代碼中斷

0044A26A cvtsi2sd xmm1,dword ptr [esp + 14h]

所以問題出現在“代碼生成/啟用增強指令集”編譯器選項中。 它被設置為“/ arch:SSE2”,並在不支持SSE2的機器上崩潰。 我已經將此選項設置為“未設置”,錯誤消失了。 唷!

非常感謝您的幫助!




4)寫一個日誌表明崩潰發生在一個局部int變量的聲明上,那怎麼可能? 內存損壞

我發現導致許多“奇怪的崩潰”是在所述對象的成員函數內部解除引用。




聽起來像堆棧腐敗給我。 我最喜歡的工具是IDA Pro 。 當然,你不能訪問用戶的機器。

一些內存檢查器很難捕獲堆棧損壞(如果確實如此)。 得到我認為最可靠的方法是運行時分析。

這也可能是由於異常路徑中的損壞,即使處理異常也是如此。 你是否打開了“捕獲第一次機會異常”? 你應該盡可能長。 在很多情況下,它會在一段時間後變得煩人。

您可以向這些用戶發送您的應用程序的選中版本嗎? 檢出Minidump處理該異常並寫出轉儲。 然後使用WinDbg進行調試。

另一種方法是寫非常詳細的日誌。 創建一個“記錄每個單一的行動”選項,並要求用戶把它打開並發送給你。 將內存轉儲到日誌。 在MSDN上查看“_CrtDbgReport()”。

祝你好運!

編輯:

回應你的評論:一個局部變量聲明的錯誤對我來說並不奇怪。 我已經看到了很多。 這通常是由於堆棧損壞。

例如,堆棧上的一些變量可能會在其邊界上運行。 之後所有的地獄都打破了。 然後,堆棧變量聲明拋出隨機內存錯誤,虛擬表被損壞,等等

任何時候我已經看到那些長時間了,我不得不去IDA專業版。 詳細的運行時反彙編調試是我知道的唯一真正能夠可靠獲取的。

許多開發人員使用WinDbg進行這種分析。 這就是為什麼我也建議Minidump。




下載Windows包的調試工具 。 正確設置符號路徑,然後在WinDbg下運行您的應用程序。 在某些情況下,它將違反訪問違規。 那麼你應該運行命令“!analyze -v”,這個命令非常聰明,應該給出一個錯誤提示。




“4)寫一個日誌表明崩潰發生在一個本地int變量的聲明上,這怎麼可能?內存損壞?

這可能表明硬件實際上是有故障的,或者被推得太硬。 看看他們是否超頻他們的電腦。




Related