当前位置:  开发笔记 > 编程语言 > 正文

捕获所有未处理的C++异常?

如何解决《捕获所有未处理的C++异常?》经验,为你挑选了5个好方法。

有没有办法捕获原本未处理的异常(包括那些在catch块之外抛出的异常)?

我并不是真的关心所有正常的清理工作,只是因为我可以捕获它,将其写入日志/通知用户并退出程序,因为这些情况下的例外通常是致命的,不可恢复的错误.

就像是:

global_catch()
{
    MessageBox(NULL,L"Fatal Error", L"A fatal error has occured. Sorry for any inconvience", MB_ICONERROR);
    exit(-1);
}
global_catch(Exception *except)
{
    MessageBox(NULL,L"Fatal Error", except->ToString(), MB_ICONERROR);
    exit(-1);
}

EvilTeach.. 26

这可用于捕获意外的异常.

catch (...)
{
    std::cout << "OMG! an unexpected exception has been caught" << std::endl;
}

没有try catch块,我认为你不能捕获异常,所以构造你的程序,所以异常的代码是在try/catch的控制下.



1> EvilTeach..:

这可用于捕获意外的异常.

catch (...)
{
    std::cout << "OMG! an unexpected exception has been caught" << std::endl;
}

没有try catch块,我认为你不能捕获异常,所以构造你的程序,所以异常的代码是在try/catch的控制下.


性能不是问题,只有当实际抛出异常时,系统才必须考虑要做什么.无论如何,当对象超出范围时,堆栈展开是应用程序必须执行的操作.另外,尝试一下 - 它很容易把try/catch放在main中,看看是否有性能损失.
main中的全局捕获(...)仍然不会捕获全局变量中的异常.例如,全局std :: vector (size_t(-1))将在调用main()之前耗尽内存.
除非抛出异常,否则在现代编译器中使用异常几乎没有成本.此时它与使用任何其他方法查找和报告错误一样昂贵.
@msalters一种解决问题的技巧是制作你的全局指针,然后在主要指针中分配它们.

2> kralyk..:

查看 std::set_terminate()


是的,您可以使用std :: uncaugth_exception()和std :: current_exception {)

3> gbjbaanb..:

您可以在Windows上使用SetUnhandledExceptionFilter,它将捕获所有未处理的SEH异常.

通常,这对于您的所有问题都已足够,因为IIRC将所有C++异常实现为SEH.



4> 小智..:

没有任何catch块,您将不会遇到任何异常.你可以在main()中使用catch(...)块(以及每个附加线程中的等效块).在此catch块中,您可以恢复异常详细信息,并且可以对它们执行某些操作,例如记录和退出.

但是,一般的catch(...)块也存在缺点:系统发现异常已由您处理,因此它不再提供任何帮助.在Unix/Linux上,此帮助将构成一个CORE文件,您可以将其加载到调试器中并查看未触发异常的原始位置.如果你用catch(...)处理它,这些信息就会丢失.

在Windows上,没有CORE文件,所以我建议使用catch(...)块.从该块开始,您通常会调用一个函数来恢复实际的异常:

std::string ResurrectException()
   try {
       throw;
   } catch (const std::exception& e) {
       return e.what();
   } catch (your_custom_exception_type& e) {
       return e.ToString();
   } catch(...) {
       return "Ünknown exception!";
   }
}


int main() {
   try {
       // your code here
   } catch(...) {
       std::string message = ResurrectException();
       std::cerr << "Fatal exception: " << message << "\n";
   }
}


Windows有.dmp文件,大致相当于核心文件,但它们会上传到Windows错误报告网站(如果用户点击"发送"),而不是乱丢用户的硬盘.此外,如果您配置了即时调试器,Windows将会进入调试器.

5> paxos1977..:

更新:这仅涵盖c ++ 98.

从Meyers的更有效的C++(第76页)中,您可以定义一个函数,当函数生成未由其异常规范定义的异常时,该函数被调用.

void convertUnexpected()
{
    // You could redefine the exception here into a known exception
    // throw UnexpectedException();

    // ... or I suppose you could log an error and exit.
}

在您的应用程序中注册功能:

std::set_unexpected( convertUnexpected );

如果函数生成一个未由其异常规范定义的异常,则会调用您的函数convertUnexpected()...这意味着只有在使用异常规范时这才有效.(


我知道这个答案早在c ++ 11标准可用之前就已经提出,但目前`std :: set_unexpected`已被弃用.
推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有