C ++异常处理失败

时间:2011-08-29 18:00:33

标签: c++ exception-handling

我在C / C ++中的异常处理非常好 - 我知道所有关于从std :: exception创建自定义类,何时抛出,什么时候回到UNIX errno之类的简单事情等等。我确实有一个在访问COTS代码时,我总是有点模糊。

如果我从COTS库中调用函数,那么:

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

如果CallCotsFunction()具有较差的异常处理或没有异常处理并执行除零或其他什么,它是否会传播到我的异常处理程序?

如果CallCotsFunction()导致sig-11或某种类型的东西会被抓住,或者所有赌注都是严重的?

3 个答案:

答案 0 :(得分:6)

在Linux上,unix信号通常不会触发异常处理程序。另外,一般来说,从信号处理程序抛出异常是不安全的(至少,你必须使用-fnon-call-exceptions进行编译;即便如此,我也看到了混合报告。)

另请注意,您应始终通过引用捕获异常,以避免切片:

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

简而言之:如果你的第三方库允许C ++异常传播而没有被捕获,是的,它会命中你的应用程序。如果它是从std :: exception或其他常见类型派生的,那么你应该能够捕获它。如果它是一些没有暴露给你的内部类型,你将无法按名称捕获它(但catch (...)应该捕获它)。 CPU异常(除以零,段错误等)不会自动触发C ++异常,除非您或库安装信号处理程序进行转换;在这种情况下,触发信号的代码必须使用-fnon-call-exceptions构建,以便堆栈展开才能正常工作。

通常,如果库触发SIGFPU或SIGSEGV等故障,则尝试使用异常进行恢复的结果是不可预测的;库可能不会期望在此时展开其堆栈,并且使用SIGSEGV,您可能会发生堆损坏,导致异常抛出系统本身出错。我不建议尝试以这种方式恢复 - 只是让过程死亡。

答案 1 :(得分:0)

信号独立于C ++异常并且早于C ++异常。

您的库可以捕获被零除的情况,在这种情况下,库可能会引发真正的C ++异常,或者它会被CPU捕获,从而导致信号终止您的进程。

我不建议在信号处理程序中抛出C ++异常。

答案 2 :(得分:0)

该函数未捕获的任何异常都将传播给调用者。调用者是否应该去寻找这样的例外是另一回事,取决于whether the caller can reasonably do anything about it。例如,如果函数除以零并且发生异常,那么其他所有状态是什么状态?如果您不知道,那么允许程序继续运行是否真的明智?

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