c++ - 使用 catch(...)(省略号)进行事后分析

标签 c++ exception-handling debugging try-catch ellipsis

有人提出不同的问题建议使用 catch(...)通过包围整个 main() 来捕获所有其他未处理的 - 意外/不可预见的异常与 try{}catch(...){} block 。

这听起来是一个有趣的想法,可以节省大量调试程序的时间,并至少留下一点线索。

问题的本质是可以通过这种方式恢复哪些信息(除了我留下的任何调试全局变量),以及如何恢复它(如何访问并识别任何 catch 被调用)

此外,还有哪些注意事项与之相关。特别是:

  • 它会与稍后发芽的线程一起使用吗?
  • 它不会破坏处理段错误(在其他地方作为信号捕获)
  • 它不会影响其他不可避免地嵌套在其中的 try...catch block ,它们可以处理预期的异常吗?

最佳答案

是的,这是个好主意。

如果您让一个异常逃逸 main,这是实现定义的天气,堆栈在应用程序关闭之前展开。所以在我看来,你必须在 main 中捕获所有异常。

然后问题就变成了如何处理它们。
某些操作系统(请参阅 MS 和 SE)提供了一些额外的调试工具,因此在捕获异常后重新抛出异常很有用(因为无论如何堆栈现在已经展开)。

int main()
{
    try
    {
        /// All real code
    }
    // I see little point in catching other exceptions at this point 
    // (apart from better logging maybe). If the exception could have been caught
    // and fixed you should have done it before here.

    catch(std::exception const& e)
    {
         // Log e.what() Slightly better error message than ...
         throw;
    }
    catch(...)   // Catch all exceptions. Force the stack to unwind correctly.
    {
        // You may want to log something it seems polite.
        throw;  // Re-throw the exception so OS gives you a debug opportunity.
    }
}
  • will it play nice with threads that sprout later?

它应该对线程没有影响。通常您必须手动加入任何子线程以确保它们已退出。没有明确定义主退出时子线程会发生什么的确切细节(因此请阅读您的文档),但通常所有子线程都会立即死亡(不涉及展开其堆栈的令人讨厌和可怕的死亡)。

如果您在谈论子线程中的异常。同样,这没有很好的定义(所以请阅读您的文档),但是如果线程通过异常退出(即用于启动线程的函数由于异常而不是返回而退出),那么这通常会导致应用程序终止(同样的影响如上)。所以最好阻止 ALL 异常退出线程。

  • will it not break handling segfaults (captured elsewhere as signal)

信号不受异常处理机制的影响。
但是因为信号处理程序可能会在堆栈上放置一个奇怪的结构(为了他们自己的返回处理返回到正常代码),所以从信号处理程序中抛出异常不是一个好主意,因为这可能会导致意外结果(并且绝对不可移植)。

  • will it not affect other try...catch blocks inevitably nested inside, that are there to handle expected exceptions?

应该对其他处理程序没有影响。

关于c++ - 使用 catch(...)(省略号)进行事后分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2183113/

相关文章:

c++ - 使用所有可用的内核和 CPU 是不负责任的吗?

c# - 我没有在 DLLImport 中使用的引用中看到 DLL

c# - 如何捕捉 "Unhandled win32 exception occured in AppName [procId]."

c# - Web API 2 OData错误消息作为XML返回

java - 在 Java 调试器中获取方法结果

c++ - 相当于 `using` s 的 `template` 别名

c++ - 除了使用 str.substr( ) 在给定位置提取子字符串之外,还有其他方法吗?

c# - '调用与指定绑定(bind)约束匹配的类型的构造函数引发异常

python - 有什么方法可以使用 Pycharm 调试在终端中运行的脚本吗?

ruby-on-rails - Rails 打印(转储)变量