除錯Release發布版程式的Crash錯誤(五)

2021-05-26 09:17:36 字數 2112 閱讀 3202

當我們把自己的release版本程式發布出去以後,一般都是在使用者的機器上執行。這種情況下,對於第四種方案,因為需要pdb檔案才能夠正確生成 堆疊呼叫的函式行號及**行號,因此方案四隻適用於本地release版的除錯,否則只能生成不完整的堆疊資訊。對於前三種方案,其實只需要使用者告知崩潰 位址,然後在本地查詢crash位址就可以了,但是定位crash的過程非常不方便,如果crash的情況比較多,前三種方案都不合適。而且,前三種方案 均不能生成堆疊呼叫資訊,對於debug的作用有限。

下面我們就來看乙個更加完善的解決方案。

方案五:

setunhandledexceptionfilter + minidump

setunhandleexceptionfilter函式我們已經介紹過了,本方案的思路還是要利用我們自己的異常處理函式,來生成minidump檔案。

1、minidump概念

minidump(小儲存器轉儲)可以理解為乙個dump檔案,裡面記錄了能夠幫助除錯crash的最小有用資訊。實際上,如果你在 系統屬性 -> 高階 -> 啟動和故障恢復 -> 設定 -> 寫入除錯資訊 中選擇「小記憶體轉儲(64 kb)」的話,當系統意外停止時都會在c:/windows/minidump/路徑下生成乙個.dmp字尾的檔案,這個檔案就是minidump檔案,只不過這個是核心態的minidump。

我們要生成的是使用者態的minidump,檔案中包含了程式執行的模組資訊、執行緒資訊、堆疊呼叫資訊等。而且為了符合其mini的特性,dump檔案是壓縮過的。

2、生成minidump檔案

生成minidump檔案的api函式是minidumpwritedump,該函式需要dbghelp.lib支援,其原型如下:

bool winapi minidumpwritedump(

__in          handle hprocess ,

__in          dword processid ,

__in          handle hfile ,

__in          minidump_type dumptype ,

__in          pminidump_exception_information exceptionparam ,

__in          pminidump_user_stream_information userstreamparam ,

__in          pminidump_callback_information callbackparam

);在我們的異常處理函式中加入以下**:

handle hfile = ::createfile( _t("e:"), generic_write, 0, null, create_always, file_attribute_normal, null);

if( hfile != invalid_handle_value)

其中,pexinfo變數為異常處理函式pexception_pointers型別的引數。具體請參考msdn。

3、除錯minidump

除錯dump檔案首先需要pdb檔案,因此我們build程式時需要設定 debug infomation format 為 「program database(/zi)」。其次,我們還要確保所用的dump檔案與源**、exe、pdb檔案版本是一致的,這要求我們必須維護好程式版本資訊。

除錯minidump最方便的環境就是vs了,我們只要將.dmp、.exe、.pdb檔案放在乙個路徑下,保證源**檔案的路徑與編譯時的路徑一致就可以了,剩下的就是vs幫我們完成。雙擊.dmp檔案或者在檔案開啟工程中選擇「dump files」,載入dump檔案,然後按f5執行就能直接恢復crash時的現場了,你可以定位crash的**,可以檢視呼叫堆疊,可以檢視執行緒和模組資訊...一切都跟你設定斷點除錯一樣,太強大了!看個截圖吧。

需要注意的是,對於release版的程式來說,很多**是經過編譯器優化過的,因此定位的時候可能會有所偏差,大家可以考慮設定選項去掉**優化。

本文主要參考了這篇文章: 。

除錯Release發布版程式的Crash錯誤(一)

非常感謝作者提供了乙個系統的解決方案 在windows平台下用c 開發應用程式,最不想見到的情況恐怕就是程式崩潰,而要想解決引起問題的bug,最困難的應該就是除錯release版本了。因為release版本來就少了很多除錯資訊,更何況一般都是發布出去由使用者使用,crash的現場很難保留和重現。本文...

除錯Release發布版程式的Crash錯誤(一)

在windows平台下用c 開發應用程式,最不想見到的情況恐怕就是程式崩潰,而要想解決引起問題的bug,最困難的應該就是除錯release版本 了。因為release版本來就少了很多除錯資訊,更何況一般都是發布出去由使用者使用,crash的現場很難保留和重現。本文將給出幾個解決方案,完成對 rele...

除錯Release發布版程式的Crash錯誤(二)

方案二 崩潰位址 map檔案 cod檔案 由於vc8以後的版本都不再支援map檔案中產生 行資訊,因此我們尋找另一種定位方式 cod檔案。1 cod檔案 cod檔案是乙個包含了彙編碼 二進位制機器碼和源 對應資訊的檔案,每乙個cpp都對應乙個cod檔案。通過這個檔案,我們可以非常方便地進行定位。在v...