捕获C ++库崩溃的一致方法

时间:2014-08-05 18:42:45

标签: c++ exception memory crash atexit

我在不同的网站上环顾四周,找不到这个问题的任何答案,除了看起来不会起作用的问题。正如标题所说,我正试图找到一种方法来捕捉我正在处理的图书馆崩溃。我有一个Root类,它包含我在库中拥有的许多经理风格的类的实例,并在它的析构函数中释放实例。当然,管理人员负责相当多的数据,所以如果他们没有得到妥善处理,就有可能出现相当不可接受甚至危险的内存泄漏。

我知道,当程序崩溃时,操作系统将释放程序的堆栈空间,但这不包括调用已分配对象的析构函数。它也不包括删除在执行期间分配的任何堆,这就是我处理库中大量内存的方式,这可以追溯到广泛的内存泄漏问题。

我在其他网站上遇到的大量答案只是说用atexit()注册一个函数,但如果应用程序崩溃,该函数不起作用。并且,如上所述,由于崩溃不会调用析构函数,因此无法创建一个全局单例,在它被销毁时关闭所有内容,这是我最初的想法如何处理它。我的另一个想法是希望图书馆的最终用户采取适当的预防措施以避免崩溃(通过广泛使用异常抛出),但我觉得这违背了编码良好的库的想法,坦率地说我认为它要求最终用户处理这个问题。

所以我想我的TL; DR问题是这样的:有没有办法,通过标准的C ++函数,或通过某种类型的管理器类来捕获库崩溃并适当处理它?<​​/ p> 编辑:另外,我真的更喜欢跨平台的方式来处理这个问题。我的代码库大量使用C ++ 11的功能,因此我以编程方式将可用编译器限制为最新版本的GCC和Clang。

不仅如此,我还有一些类,比如Logger,它们将关闭它们到文件系统的流并打印出一些关于退出状态的消息。我还有一个内存跟踪器,可以将任何可能的内存泄漏报告给文件,但只能在它的析构函数中报告。

2 个答案:

答案 0 :(得分:2)

  

&#34;有没有办法,通过标准的C ++函数,或通过某种类型的管理器类来捕获库崩溃并适当处理它?&#34;

我能想象的问题最简洁的答案是:

  

坚持使用C++ Standard Error handling的类和类别。


正如您要求的atexit(),行为也在standard reference中明确定义。

注意还有一些像std::terminate_handler这样的处理程序机制,允许您以便携和标准的方式处理一些特殊的中止情况。

最后但并非最不重要的是,可能需要安装某些(特定于操作系统的)signal handlers,以捕获由于堆栈溢出或类似事件而引发的所谓segmentation fault (SIGSEV)错误。

答案 1 :(得分:1)

  

所以我想我的TL; DR问题是:有没有办法,要么通过   标准C ++函数,或通过某种类型的管理器类来捕获   当图书馆崩溃并妥善处理它时?

存在诸如结构化异常处理和各种分段错误和总线错误(标准对这些事情没有任何说明)之类的事情,防止库中崩溃导致用户失败的唯一方法应用程序是通过客户端程序执行的二进制文件提供库,并让客户端负责监视客户端进程是否死亡。

如果您希望将库直接链接到用户的应用程序,那么您无法做任何事情以确保您的库中的错误不会导致崩溃用户的申请。这是单元,子系统和系统测试套件的用途。请记住,如果您的库崩溃应用程序几乎每个我知道的操作系统都将回收它分配的所有资源,因此您不需要全局单例来释放堆内存:它将自动声明在崩溃时通过操作系统。

最后请注意,如果库崩溃,则进程已处于错误状态。您无法安全地执行任何代码(例如,如果进程堆已损坏),包括编写日志消息或转储内存泄漏状态。