2011-08-22 112 views
5

我目前正面臨着我的團隊正在處理的大型複雜項目中遇到的最惡毒的錯誤之一。我們使用C++作爲編程語言,目前使用Visual Studio進行開發,儘管最終產品旨在運行跨平臺。描述並發現導致看似隨機崩潰的狀態腐蝕問題

的錯誤:

有一個在我們的系統在執行看似隨機點觸發崩潰的錯誤。崩潰原因通常是每次執行程序時都會更改的地址讀訪問衝突。有時我們也會收到堆損壞錯誤。調用堆棧導致我們在代碼庫中發生變化,而很少發生到某些外部庫(我們的例子中是Lua),這些錯誤顯然不在此處。

看起來好像這個bug在過去4個月裏一直在發展。這段時間之前,大致上,我的一些團隊成員看到前端程序崩潰的方式和位置與現在發生的情況非常相似。

更多的細節:

我們的代碼庫是純C的大約800K行++(註釋除外)大,超過3年的課程開發。目前的項目重約30萬。我們已經使用了過多的單元測試和其他方法來消除錯誤,例如斷言,智能指針等。

其他人和我一直在試圖找到這個bug超過2個星期了。這對我來說已經不僅僅是一場噩夢。在這樣一個複雜的項目中,即使是舊的printf調試,在面對現在複雜的情況下似乎也會失敗。

我的問題

  • 在我們這裏面臨什麼樣的錯誤呢?甚至有這個名字嗎?這種錯誤在其他大型項目中多多少少出現過?

  • 在使用各種實用程序,在各種平臺和各種構建設置上花費了2個星期的無果調試之後,我們可以如何找到並消除它?

(我以前的問題被關閉,所以我想有更多的細節更好,制定這個時候,鏈接:https://stackoverflow.com/questions/7154645/how-is-this-kind-of-bug-called

+0

阿爾夫,零星的臭蟲是最糟糕的。學習使用調試工具的時間。 –

回答

8

您所描述的症狀是典型的堆損壞的(不所有的堆損壞都會報告錯誤信息!)。您需要審覈程序中所有對象的生命週期;確保你沒有兩次釋放事物,或釋放它們後使用它們,並確保你沒有溢出任何緩衝區。您可能想借此機會使用諸如std::smart_ptr(或boost::smart_ptr)之類的內容來自動執行堆管理的各個部分。

如果您在Linux或Mac OS上,請嘗試在valgrind下運行程序 - 它會檢測到許多堆和堆棧損壞錯誤。在Windows上,使用application verifier;它可以幫助使錯誤更接近實際發生的時間點。

如果使用線程,導致堆損壞的競爭條件是另一種可能性。審覈你的鎖定機制。

如果你可以很容易地重現這個錯誤,並且有一個源代碼管理系統,考慮一個二等分來確定它是什麼時候被引入的。也就是說,在您的源代碼歷史記錄上執行二進制搜索以找到第一次提交錯誤。 Git有自動執行此操作的工具 - git-bisect - 如果您尚未使用git,則可以將庫的副本導入到git中以運行此工具。

此外,請查看您是否可以禁用程序的某些部分(防止有問題的代碼被調用)以嘗試縮小問題的範圍。請注意,這可能有誤報 - 如果禁用模塊X並停止崩潰,則可能意味着模塊X正在損壞堆,或者可能意味着模塊W損壞了堆,而模塊X恰好在發現它時很好。

+1

非常好的一點。雖然請注意,平分零星的錯誤是非常困難的。 – Owen

+0

@Owen,因此「如果你可以很容易地重現」...:/ – bdonlan

+0

啊真的錯過了。 – Owen

0

只是補充Bdonlan的外觀極好的回答:因爲你是爲Windows開發代碼,並與大項目的工作,我會強烈建議你買的「高級Windows調試」的書,用WinDbg中,AppVerifier的和其他類似的工具結識。這將是非常值得的投資。 在這本書中,整個章節專門討論堆腐敗問題,正如前面的回答中已經提到的那樣,最可能是你面臨的問題。