2009-09-03 194 views
14

我有一個第三方庫有時會拋出一個異常。所以我決定換我的代碼在一個try/catch(...),這樣我可以記錄有關發生的異常信息(無具體細節,只是它發生了。)無法捕捉C++異常使用catch(...)

但由於某些原因,該代碼仍然崩潰。在客戶端計算機上,它崩潰並且在catch(...)中記錄異常的代碼從未得到執行。如果我在我的調試/開發機器上運行這個,我會彈出一個詢問我是否需要調試的問題。當我這樣做時,它會報告0xC0000005:訪問衝突讀取位置XXX。

奇怪的是,使用舊版本的第三方庫時,完全相同的代碼會捕獲異常,並且記錄異常的代碼將執行。 (我證實了這一內VS看會發生同樣的情況。)

這裏是正在執行的僞代碼:

所以我有兩個問題:

  1. 有一些變化在第三方可能編譯庫的方式,以便我的代碼將無法捕捉異常? (是的,如果我知道要告訴他們什麼,我可以讓第三方爲我做出必要的修復和重新編譯。)

  2. 假設我無法讓第三方修復它,我能做些什麼來抓住這些例外情況?我正在考慮...有沒有辦法讓我確定pObject是否被釋放了?

回答

11

AFAIK訪問衝突不會拋出異常......至少不是標準的!

也許捕捉特定Windows的「原生」的異常將有助於:http://www.gamedev.net/reference/articles/article2488.asp

+0

哇這是一篇非常有用的文章,實際上對我來說確實包含一個可行的解決方案......舊的庫必須在VS2003下構建,而新的庫適用於VS2008--這是至關重要的區別。將我的庫設置爲編譯w /選項「啓用C++異常:是有SEH異常(/ EHa)」我的代碼現在捕獲此實例。出於這個原因,我正在授予這個答覆的正確答案。 但是我想說的是,其他幾個答案提供了有效的有用信息,特別是關於「在繼續使用中沒有多大用處」的答案,所以謝謝大家! – 2009-09-03 14:46:26

+4

用C++ try/catch捕捉SEH異常通常是一個糟糕的主意。 MS爲什麼在新編譯器中默認禁用它是有原因的。通常,您應該使用SEH構造(如__try/__ except),而不是啓用該編譯器選項。 – jalf 2009-09-03 15:11:25

+0

Michael Bray>沒問題,我想這裏有很多答案可以幫助解決這類問題。我也會投票給其他人,以便在這個答案下做出決定。 jalf>確實。這就是他們在文章中所做的。 – Klaim 2009-09-03 16:16:58

0

你描述的看起來非常像::結束()是由C++運行時調用。

這通常是由所謂的雙重例外引起的 - 某處引發異常,堆棧展開開始,並且在堆棧展開期間調用的析構函數之一也引發異常。在這種情況下:: terminate()被調用,你不能真正幫助程序。

如果是這種情況,唯一的解決辦法是獲取庫的新版本,其中異常不會在析構函數外發生。你可以很容易地驗證 - 庫已經加載電話:: set_terminate(後),並提供自己的函數,並檢查其是否被之前的程序崩潰調用。

1

如果你是Windows平臺上,你可以嘗試尋找__try

上。然而,請注意,沒有,除非你真的確定你可以隔離和處理異常繼續執行多大用處。

8

訪問衝突是不是一個C++異常。這是一個Windows結構化異常。如果你想捕捉它們(...),你必須使用_set_se_translator()。

你或許應該谷歌的所有原因,趕上(...)是邪惡的,並確保你真的想這樣做。

+0

這是一個很好的信息......但在我的情況下,似乎我必須在main()函數中使用_set_se_translator()(至少根據上面sharptooth引用的文章中的示例).. 。我沒有提到的一件事是,我的代碼實際上是另一個應用程序(第三方應用程序,實際上)加載的com對象,我無法控制正在使用的main()。否則,我認爲這將是最好的道路。 – 2009-09-03 14:48:50

+0

Ooops我的意思是Klaim在文章中的參考。抱歉! – 2009-09-03 14:49:52