2011-08-29 188 views
0

我很擅長處理C/C++中的異常 - 我知道所有關於從std :: exception創建定製類,什麼時候拋出,什麼時候退後一步等簡單的東西,如UNIX errno等。儘管談到訪問COTS代碼,我確實有一件事情我總是有點模糊。C++異常處理失敗

如果我調用一個函數從COTS庫,像這樣:

void DoSomething() 
{ 
    try 
    { 
     CallCotsFunction(); 
    } 
    catch (CotsException& ce) 
    { 
     //Cots error caught 
    } 
    catch (...) 
    { 
     //Unknown error caught. 
    } 
} 

如果CallCotsFunction()有差的異常處理或沒有異常處理和執行除以零或什麼的,會得到它傳播到我的異常處理程序?

如果CallCotsFunction()導致一個sig-11或類似的東西,它會被抓住,或者是所有的賭注與嚴重的東西?

回答

6

在Linux上,unix信號通常不會觸發異常處理程序。此外,一般來說,從信號處理程序拋出異常是不安全的(至少,您必須編譯-fnon-call-exceptions;即使這樣我看到了混合報告)。

還請注意,你應該總是通過引用捕獲異常,避免切片:

catch (CotsException &ce) 
{ 
    // ... 
} 

簡而言之:如果您的第三方庫可以讓C++異常傳播,而不會被抓,是的,它會打你的應用程序。如果它是從std :: exception或其他常見類型派生的,則應該能夠捕獲它。如果某種內部類型沒有暴露給您,您將無法通過名稱獲知它(但catch (...)應該可以捕獲它)。 CPU異常(除以零,segfaults等)不會自動觸發C++異常,除非您或庫安裝了一個信號處理程序來轉換它;在這種情況下,必須使用-fnon-call-exceptions來構建觸發信號的代碼,以使堆棧展開以正常工作。一般來說,如果庫觸發諸如SIGFPU或SIGSEGV之類的錯誤,試圖恢復異常的結果是不可預測的;圖書館可能不會期望在這一點上展開它的堆棧,並且使用SIGSEGV,您可能會導致異常拋出系統本身出現故障。我不會建議以這種方式恢復 - 只是讓這個過程死去。

+0

謝謝,沒有忘記參考 - 編輯問題來匹配它:) –

0

信號是獨立的,並且早於C++異常。

零除可以被你的庫捕獲,在這種情況下,庫可以拋出一個真正的C++異常,或者它會被你的CPU捕獲,導致信號終止你的進程。

我不會建議從信號處理程序中拋出C++異常。

0

任何未被函數捕獲的異常都會傳播給調用者。呼叫者是否應該打擾捕捉這樣的異常是另一回事,取決於whether the caller can reasonably do anything about it。例如,如果函數除以零,並且發生異常,那麼其他狀態是什麼狀態?如果你不知道,那麼允許程序繼續運行真的很明智嗎?

我會以同樣的方式處理信號處理。如果您沒有被告知期望第三方庫觸發信號,那麼您不應該嘗試處理它們。

相關問題