天天看點

C++ debug下情況良好、release下頻繁奔潰問題的跟蹤與解析

        最近一段時間一直忙于開發新平台系統的功能,今天測試那邊拿過來簡單的測試一下,并對相關需求和功能點進行驗證。結果出現了一個奇怪的問題:在驗證某個功能點時,在release模式下的程式頻繁出現奔潰現象。之前在開發該功能點時也進行了充分的測試,程式一直運作正常,怎麼一到release模式下就出現頻繁奔潰的現象呢?

        由于還在新功能的開發過程中,本想測試中的小問題可以留到後面正式測試時再解決,畢竟時間點比較緊,實作既定的功能是第一位的。但是對于這種頻繁奔潰的問題,測試那邊肯定很是惱火的,就連我自己也看不過去了,時間再緊也得先解決這個問題。于是,仔細走讀了上述功能點的代碼,也沒發現什麼問題,而且要命的是debug下沒有發生奔潰的問題。其實也知道,這可能是與程式在debug下和release下的不同特性導緻的,比如:變量在debug下即使沒有初始化,編譯器也會去初始化,而在release下則不會,會使用随機值;debug下有大量調試資訊,有記憶體保護,出現奔潰的幾率要小一點,而release下卻沒有這樣的保護。  本來在程式中植入了華生醫生,以便在程式出現異常時利用華生醫生産生的日志檔案,結合IDA工具對異常點進行定位。但是不幸的是,在出現奔潰的時候并沒有産生日志檔案,這樣就比較棘手了。由于debug下很難複現,release下又沒有奔潰日志,加上系統的代碼量很大,隻能修改工程在release下配置,在release下進行調試了。結果在release下調試很快找到了問題,問題在于某行代碼對空指針操作了。那麼既然是空指針,那麼debug下和release下的截然不同的表現作何解釋呢?出問題的代碼與上述功能點沒直接的聯系,于是找到相關責任同僚,讓其查一下其負責的子產品,怎麼出現了對空指針操作的情況。待找到可能的出錯的代碼點時,我過去看了一下,結果終于可以真相大白了:同僚定義的變量,由于使用了if判斷語句導緻if内的語句沒有執行導緻變量沒有初始化,在debug下沒問題,因為編譯器會對該變量初始化,而在release下變量中存放就是随機值了,導緻接下來的if判斷語句條件為真,進入了出錯的函數中去了,進而導緻程式的奔潰(在出錯的函數中并沒有對指針進行是否為NULL的判斷)。這就很好解釋了為什麼程式在debug下和release下的不同表現了。

        花了很大的精力才最終解決上面的問題。從中我們也能總結一些東西:平時寫代碼一定要規範,變量一定要初始化,指針變量要做是否為NULL的判斷等等。由于這個同僚是剛畢業的,編碼經驗相對比較少,一方面代碼不夠規範,另外代碼沒有進行仔細的走讀才導緻了上面的問題。是以,我們平時還是要多強調編碼的規範性,特别是對剛畢業的新同僚,應該更要強調這一點,因為規範性在提高代碼可讀性的同時,也可以減少代碼出錯的幾率。這點在大型系統的開發中也尤為重要。

       下面給出在VC6.0中如何在release模式下進行調試的辦法。隻要在工程的C++ tab頁面和Link tab頁面中進行如下的配置就可以了。

       1、在C++ tab頁面中:

             category:General  

             Optimizations:Disable(Debug)

             Debug info: program database

             如下所示:

C++ debug下情況良好、release下頻繁奔潰問題的跟蹤與解析

       2、在Link tab頁面中:

             category:General  

             勾選 General debug info

             勾選 General mapfile

             如下所示:

C++ debug下情況良好、release下頻繁奔潰問題的跟蹤與解析

繼續閱讀