2011-08-29 192 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。例如,如果函数除以零,并且发生异常,那么其他状态是什么状态?如果你不知道,那么允许程序继续运行真的很明智吗?

我会以同样的方式处理信号处理。如果您没有被告知期望第三方库触发信号,那么您不应该尝试处理它们。

相关问题