如果发生未处理的异常,C ++是否提供了一种“显示”视觉效果的方法?
我想要做的是assert(unhandled exception.msg())
如果实际发生的话(如下例所示):
void foo() {
throw std::exception("Message!");
}
int main() {
foo();
}
我希望这种代码不会立即终止(因为异常未处理),而是显示自定义断言消息(实际上是Message!
)。
这可能吗?
答案 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)
如果您真的对导致程序失败的事情感兴趣,可以通过检查事后调试器中的过程映像来获益。精确的技术在操作系统与操作系统之间略有不同,但基本的思路是先启用核心转储,然后使用调试符号编译程序。程序崩溃后,操作系统会将其内存复制到磁盘,然后您可以在崩溃时检查程序的状态。