【问题标题】:Global exception handling in C++C++ 中的全局异常处理
【发布时间】:2011-05-20 23:39:37
【问题描述】:

我可以在 C++ 中实现全局异常处理吗? 我的要求是 try...catch 块没有在一段代码中使用,那么应该有一个全局异常处理程序来处理所有未捕获的异常。

我能实现吗,请提出宝贵的建议:)

【问题讨论】:

  • C 中没有 try...catch 块。你可能在考虑 C++ 吗?
  • 谢谢Karl,我已经改成c++了。
  • 这个 MSDN 论坛帖子可能会提供一些有用的链接:social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/…
  • 您是否只需要捕获 C++ 异常或系统错误,例如访问冲突?

标签: c++ exception-handling global


【解决方案1】:

我总是将最外层的函数包装在这样的 try-catch 中:

int main()
{
   try {
      // start your program/function
      Program program; program.Run();
   }
   catch (std::exception& ex) {
      std::cerr << ex.what() << std::endl;
   }
   catch (...) {
      std::cerr << "Caught unknown exception." << std::endl;
   }
}

这将捕获所有内容。 C++ 中良好的异常处理不是要全部编写 try-catch,而是要捕获您知道如何处理它的地方(就像您似乎想要做的那样)。在这种情况下,唯一要做的就是将错误消息写入 stderr,以便用户对其进行操作。

【讨论】:

  • Daniel,如果您使用区分结构化和非结构化异常处理的 VC++,有几种异常不会被 catch(...) 捕获。
  • 但那些不是 C++ 例外。 (并且 Linux 中的等效错误也不会被 try/catch 捕获)
  • 好吧,发帖人只说他使用的是 C++。没有提及任何平台细节。
  • 这不是一个全局异常处理程序。例如,此技术在使用其他语言的 C++ 代码时不起作用。因此,我认为它不能回答问题。
  • @Dmitry 什么时候未捕获的异常是“良好的线性流”?对不起,如果我误解了......
【解决方案2】:

您可以使用set_terminatecurrent_exception() 的组合

【讨论】:

  • 你应该举个例子。这个答案解决了最有用的问题。
  • 查看我的答案以获取示例。 | ping @ChrisWatts
【解决方案3】:

在 C++ 中,当未捕获异常时调用 terminate 函数。您可以使用set_terminate 函数安装您自己的终止处理程序。缺点是您的终止处理程序可能永远不会返回;它必须使用某些操作系统原语来终止您的程序。默认只是调用abort()

【讨论】:

  • 对不起,我是一名 C# 程序员。因此,如果您可以提供一些代码示例,以便对我有所帮助。在此先感谢:)
  • @DeviprasadDas cplusplus.com/reference/exception/set_terminate 有一个例子。 std::set_terminate(myterminate); 其中 myteriminate() 只是一个普通的 void 函数
【解决方案4】:

我也想这样做,这就是我想出的

    std::set_terminate([]() -> void {
        std::cerr << "terminate called after throwing an instance of ";
        try
        {
            std::rethrow_exception(std::current_exception());
        }
        catch (const std::exception &ex)
        {
            std::cerr << typeid(ex).name() << std::endl;
            std::cerr << "  what(): " << ex.what() << std::endl;
        }
        catch (...)
        {
            std::cerr << typeid(std::current_exception()).name() << std::endl;
            std::cerr << " ...something, not an exception, dunno what." << std::endl;
        }
        std::cerr << "errno: " << errno << ": " << std::strerror(errno) << std::endl;
        std::abort();
    });
  • 除了检查 what() 之外,它还检查 ernno/std::strerror() - 将来我也打算通过 exeinfo/backtrace() 添加堆栈跟踪

  • catch(...) 是为了以防有人抛出异常以外的东西.. 例如 throw 1; (throw int :| )

【讨论】:

  • 谢谢@hanshenrik,这非常有帮助。看起来您在第一行确实有语法错误。我之前没有使用过 set_terminate,所以如果你能修复它,我将不胜感激。
  • @KellyStevens 不,我认为这很好,它被称为“lambda 函数”,它需要 c++11 或更高版本(例如,它不适用于 c++03 编译器),检查wandbox.org/permlink/MTAI7OrWoGRYrbMX
【解决方案5】:

当引发异常时,如果当时没有被捕获,它会沿着层次结构向上直到它被实际捕获。如果没有处理异常的代码,程序将终止。
您可以在终止前运行特定代码,使用您自己的 set_unexpectedset_terminate 处理程序进行清理

【讨论】:

  • 对于这个和所有其他关于 set_terminate 的答案:如果异常没有在 catch 块中处理,进程仍然会终止。
猜你喜欢
  • 1970-01-01
  • 2016-11-03
  • 2019-07-18
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 2011-09-29
相关资源
最近更新 更多