2014-05-08 99 views
6

我遇到了一個測試程序的問題,我的應用程序在初始化時崩潰。我添加了更多的日誌記錄和異常處理,但它仍然與通用的「此程序已停止工作」消息崩潰,而不是觸發我的錯誤處理。catch(...)沒有捕捉到異常,我的程序仍然崩潰

鑑於我的主要()看起來像這樣,並有catch(...)在什麼情況下,這不會被觸發?

try{ 
    simed::CArmApp app(0, cmd); 
    for(bool done = false;!done;) 
    { 
     done = !app.frame(); 
    } 
} catch(const std::runtime_error &e){ 
    handleApplicationError(e.what()); 
    return -1; 
} catch(...) { 
    handleApplicationError("Unknown Error"); 
    return -999; 
} 

我的代碼調用了一個庫,在做OpenGL渲染,這是我認爲事情出錯的地方。

+1

我不確定我是否理解。你怎麼知道這是一個未捕獲的異常? – kec

+0

因爲'handleApplicationError'沒有被調用(它引發了一個MessageBox並殺死了我的啓動畫面,這些都沒有發生) –

+0

但是爲什麼它不能僅僅是一些其他類型的程序崩潰? – kec

回答

7

如果C++ catch(...)塊沒有捕獲錯誤,可能是因爲Windows錯誤。

在Windows上有一個叫做Structured Exception Handling的概念,當不良事件發生時,操作系統會引發「異常」,比如取消引用無效的指針,除以零等。我說「異常」,因爲這些不是C++異常;相反,這些是Windows以C風格定義的嚴重錯誤 - 這是因爲Win32是用C語言編寫的,所以C++異常是不可行的。

參見:根據意見

更新

如果你想用C++異常處理和SEH也許你可以嘗試以下(未經測試)代碼:

__try 
{ 
    try 
    { 
     // Your code here... 
    } 
    catch (std::exception& e) 
    { 
     // C++ exception handling 
    } 
} 
__except(HandleStructuredException()) 
{ 
    // SEH handling 
} 
+0

有趣的是,謝謝你,我現在並不清楚我是如何實現這兩個的 - 或者更確切地說,在我的示例代碼中,我應該如何編寫它以保證更安全。 lib是事情正在破壞的地方 - 這個lib確實會拋出C++異常,所以我希望他們抓住了s對我來說這些問題!是否有可能使用我的代碼作爲例子做什麼,作爲一個完美的答案? –

+0

我已經添加了一些示例代碼,也許這可以用來捕獲兩種異常 –

+0

yuck(必須這樣做,而不是您的代碼!)但似乎這是解決方案 –

1

你是否聲明瞭任何全局對象? 如果您在主循環外創建了任何對象,這可以解釋爲什麼它沒有被捕獲(它不在您的try-catch中)。

另外,是否可以顯示更多的應用程序?一個最小的例子?

+0

這應該是一個評論... – deviantfan

+0

它肯定會崩潰,因爲從該try/catch塊內調用的東西 - 我得到日誌記錄來證明代碼正在運行,然後它只是死,但沒有我的錯誤處理被觸發:( –

0

如果一個對象的析構函數拋出一個異常,該異常由於堆棧展開而銷燬以處理不同的異常,程序將退出catch(...)或不。

4

到目前爲止,我知道,有可能是在那裏catch(...)不能真正

比1個未處理的異常
  1. 更多的至少兩種情況:時之前先前發生異常處理的異常上升,那麼C++無法處理它,並且應用程序會崩潰。
  2. 投擲例外不在例外列表規範:如果任何方法拋出異常,其不處於異常規範列表(在任何)然後unexpected將被稱爲它調用abort
+0

+1,但在#1情況下,它不是一個簡單的「崩潰」,而是一個對std :: terminate的調用 – Angew

+0

@Angew,對,默認情況下是'terminate'也會調用'abort',和#2一樣 – Rakib

相關問題