C ++未处理的异常

时间:2010-09-22 23:16:12

标签: c++ exception handler

如果发生未处理的异常,C ++是否提供了一种“显示”视觉效果的方法?

我想要做的是assert(unhandled exception.msg())如果实际发生的话(如下例所示):

void foo() {
   throw std::exception("Message!");
}

int main() {
 foo();
}

我希望这种代码不会立即终止(因为异常未处理),而是显示自定义断言消息(实际上是Message!)。

这可能吗?

8 个答案:

答案 0 :(得分:11)

标准没有指定实际显示未捕获异常的消息。但是,在许多平台上,无论如何都是可能的。在Windows上,您可以使用SetUnhandledExceptionFilter并提取C ++异常信息。使用g ++(无论如何适当的版本),终止处理程序可以使用以下代码访问未捕获的异常:

   void terminate_handler()
   {
       try { throw; }
       catch(const std::exception& e) { log(e.what()); }
       catch(...) {}
   }

实际上g ++的默认终止处理程序做了类似的事情。您可以使用set_terminate设置终止处理程序。

简而言之,没有通用的C ++方式,但有些方法取决于您的平台。

答案 1 :(得分:6)

Microsoft Visual C ++允许您挂钩未处理的C ++异常like this。这是standard STL behaviour

您可以通过调用set_terminate来设置处理程序。建议您的处理程序不要工作,然后终止程序,但我不明白为什么你不能通过断言发出信号 - 虽然你没有访问导致问题的异常。

答案 2 :(得分:4)

如果您使用的是Windows,那么处理未处理的异常和崩溃的好库是CrashRpt。如果您想手动执行此操作,还可以use the following I wrote in this answer

答案 3 :(得分:4)

我认为你会受益于如下所述的全面陈述:

int main() {
 try {
   foo();
 catch (...) {
   // Do something with the unhandled exception.
 }
}

答案 4 :(得分:1)

如果我正确地阅读了您的问题,那么您会询问是否可以重载throw(更改其默认行为),以便它执行用户定义的操作。不,你不能。

编辑:因为你坚持不懈:),这是一个坏主意™:

#include <iostream>
#include <stdlib.h>
#include <windows.h>

void monkey() {
   throw std::exception("poop!");
}

LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
    std::cout << "poop was thrown!" << std::endl;
    return EXCEPTION_EXECUTE_HANDLER;
  }

int main() {
    SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
    monkey();
    return 1;
}

同样,这是一个非常糟糕的主意,它显然取决于平台,但它确实有效。

答案 5 :(得分:1)

是的,它可能。你走了:

#include <iostream>
#include <exception>

void foo() 
{
   throw std::exception("Message!");
}

int main() 
{
  try
  {
    foo();
  }
  catch (std::exception& e)
  {
    std::cout << "Got exception: " << e.what() << std::endl;
  }

  return 0;
}

答案 6 :(得分:0)

c ++标准是终止处理程序 - 正如其他人所说的那样

如果你追求更好的投掷可追溯性,那么这就是我们的工作

我们有一个宏Throw,它记录文件名和行号和消息,然后抛出。它需要一个printf样式的varargs消息。

Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);

我收到了很好的日志消息

Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99

答案 7 :(得分:0)

如果您真的对导致程序失败的事情感兴趣,可以通过检查事后调试器中的过程映像来获益。精确的技术在操作系统与操作系统之间略有不同,但基本的思路是先启用核心转储,然后使用调试符号编译程序。程序崩溃后,操作系统会将其内存复制到磁盘,然后您可以在崩溃时检查程序的状态。