2010-11-01 90 views
6

目前我再一次遇到這樣的情況:我必須找到導致調試器運行時幾乎從不發生Bug的原因(可能是一些競爭條件)。我能想到的唯一的東西是:查找Heisenbugs的策略

  1. 將調試打印和斷言添加到代碼中,告訴我沒有調試器時發生了什麼。
  2. 逐句通過代碼,思考每一行和可能產生的副作用。

總而言之,這是非常令人沮喪的。這些類型的錯誤有哪些策略和經驗?

編輯:我使用的是Visual C++ 2005,但我認爲這個問題適用於很多(所有)語言和開發環境。

+2

@Mitch:編輯這個問題來回答你的問題。此外,我希望這是CW,但我沒有要求立即這樣做的10K聲望,所以可以自由地爲我啓動勾號。 – 2010-11-01 09:11:06

+0

我不明白爲什麼這應該是CW(即使我可以設置它) – 2010-11-01 09:19:59

+2

@Mitch:因爲它沒有明確的答案。這更多的是分享你的經歷問題。 – 2010-11-01 09:20:53

回答

1

當所有技術都結束時,BoundsCheckers或RationalPurify沒有幫助。我通常使用非常愚蠢的技巧。我們在大學第一年就已經發現了它。在俄羅斯,它被稱爲非常粗糙。

所以 - 我從選擇在多線程環境中失敗的可疑塊/模塊開始。如果不可能,那麼程序結構將被重新考慮。

當模塊被選中時,我評論小塊代碼,直到異常消失。這可以確定究竟是什麼原因(例如競態條件)。如果在這一步你可以說出了什麼問題 - 那麼它很棒。

如果不是,應用相同的技術來檢測錯誤的前提條件,所以我會註釋掉代替罪魁禍首的代碼。

2

我發現在我的C/C++/Java代碼上運行lint並確保我修復了它提供的每個警告都導致這些競爭條件消失。但那不是解決方案。 不要巧合編碼。您必須瞭解您修復的問題以及解決問題的原因。我相信它是K(& ||)R表示大量日誌消息比其他調試器更有助於調試代碼 - 特別是在多線程環境中,但需要引用。

仔細查看導致產生錯誤的所有活動的非常詳細的跟蹤確實對確實有很大幫助。

+0

+1作爲一種策略而不是依靠調試器進行日誌記錄。 – orangepips 2010-11-01 14:11:20

4

如果你能確定的點(S),在該問題是第一個可見(不是當它顯然引起),拋出一個異常那裏使用Process Dumper以獲取事後調試轉儲。

在IDE外運行您的發行版二進制文件,然後附加調試器。這可以避免調試器內部運行的特殊堆和其他標誌。

如果您對錯誤的位置有任何想法,請將該代碼提取到儘可能最小化的測試應用程序中 - 您正試圖對其進行測試以銷燬。再次,僅在代碼啓動並運行後才附加調試器,以避免許多調試器特有的副作用。

檢查選項 - 建立/W4只是爲了確保沒有任何明顯的錯過。檢查C風格演員或reinterpret_cast的代碼和警告,以防有人丟棄了未知但重要的警告或錯誤消息。