C++,windows異常捕獲及崩潰處理?

在windows下開發遇到的一個問題:軟體以一個exe(框架)通過LoadLibrary載入多個dll(子插件)的形式開發運行。不同的dll由不同的人負責,若某個子插件代碼出了問題可能會導致整個框架崩潰。現在希望在提交給用戶使用後,子插件出問題時,框架能夠捕捉到異常或者崩潰,優雅的掛掉並能定位到問題模塊或者原因。

現在框架採取的方法是通過windows的setunhandledexceptionfilter函數和writeminidump函數來寫dump文件定位問題。但是目前的方法存在兩個問題:

1:有些錯誤捕捉不到,不會進setunhandledexceptionfilter的回調函數,如delete一個已經delete的指針:

int *num = new int;

delete num;

delete num;

2:有些錯誤捕捉到了,但是dump文件里無法通過callstack查看到堆棧信息或模塊信息。

希望各位大神不吝賜教,或者提供一些鑽研的方向

系統環境:windows.

開發語言:c++,VS2010.


你可以學習一下你使用的開發工具VS2010。它是VS系列裡面第一次把C++ intellisense獨立成一個進程的,掛掉了就打dump重啟,毫不影響VS的使用。

第二,像delete兩次這種事情根本就不應該捕捉,你不如選擇在dll裡面自己給自己打dump,沒有必要在框架裡面做,然後整個進程幹掉就好了。你強行恢復的話,也只會讓程序進入一個奇怪的狀態,從而讓甲方損失金錢,然後你就是那個無證程序員(逃


chrome 或者各種ide 之類的,對第三方插件都是單啟一個進程來載入吧,掛了也不會產生太麻煩的影響。

此外,視你的「 不同的dll由不同的人負責」 和你是什麼關係,如果是真正的未知第三方,不推薦提供dll函數介面這樣的方法來提供插件入口。


1. 寫dmp文件只能捕捉未處理異常情況下的crash,不能捕捉「錯誤」;

2. Windows承諾給你的是一個在出現未處理異常情況下的介入機會,具體的體現就是註冊一個函數指針。那麼問題就來了: 既然能註冊,那能不能反註冊? 答案是可以。

所以說沒有拋異常你肯定捕捉不到,拋異常了你也可能捕捉不到。很有可能你依賴的某個類庫默默的給你反註冊了。

3. Windows vista sp1開始,操作系統提供的寫dmp文件的功能。用戶層的應用寫一下註冊表,操作系統就會自動在出現未處理異常的情況下寫dmp文件。


不想細說了,推薦一本書(軟體調試,張銀奎著)


結構化異常處理沒用過,用過向量化異常處理,可以捕獲所有異常類型。

windows平台有四種異常處理,篩選型,結構化,向量化,c++異常處理,向量化是優先順序最高,最靈活的。(但是有時候寫的dump文件也是空的,好像說寫dump文件最好在單獨的進程?)


未列印出dump文件;列印出的dump文件很多信息是空的。

有沒有嘗試過使用調試器直接進行dump,比如WinDBG或者CBD

有些錯誤捕捉到了,但是dump文件里無法通過callstack查看到堆棧信息或模塊信息

我覺得應該是缺少必要的調試符號文件,根據題主的情況很多dll是其他公司提供的,所以估計也很難要求別人必須提供pdb文件。但是根據調用棧至少應該是可以知道奔潰是在哪個模塊產生的,這樣有確切的根據的話要求別人協助解決問題不過分吧。


推薦閱讀:

如果編譯器可以知道一個try塊不會拋出異常,那整個try-catch部分是不是會被忽略?
Python 的異常機制及規範是否相當不人性化?
Go 語言的錯誤處理機制是一個優秀的設計嗎?
各種編程語言中的「錯誤/異常處理」有哪些成熟的,優雅的或是熱門的機制/思想?

TAG:彙編語言 | C | Windows開發 | 異常處理 |