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

Consistant Way to Catch C++ Library Crashes

本文关键字:方法 崩溃 c++ 捕获      更新时间:2023-10-16

我在不同的网站上看了看,没有找到任何答案来回答这个问题,除了那些看起来行不通的。正如标题所说,我试图找到一种方法来捕捉如果我正在工作的库崩溃。我有一个Root类,它保存了我的库中许多管理器样式类的实例,并在它的析构函数中释放实例。当然,管理器负责相当多的数据,所以如果它们没有得到适当的处理,就有可能出现相当不可接受的,甚至是危险的内存泄漏。

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

我在其他网站上遇到的很多答案只是说要用atexit()注册一个函数,但如果应用程序崩溃,该函数就不起作用。而且,如上所述,由于崩溃不调用析构函数,所以没有办法创建一个全局单例,在它被销毁时关闭所有东西,这是我最初的处理方法。我的另一个想法是希望库的最终用户能够采取适当的预防措施来避免崩溃(通过广泛使用异常抛出),但我觉得这与编码良好的库的想法相悖,坦率地说,我认为它对最终用户的要求有点高。

所以我想我的TL;DR问题是这样的:有没有一种方法,要么通过标准的c++函数,要么通过某种管理器类,来捕获库崩溃并适当地处理它?

编辑:另外,我真的更喜欢跨平台的方式来处理这个问题。我的代码库大量使用了c++ 11的特性,因此我通过编程将可用的编译器限制为最新版本的GCC和Clang。

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

"有没有一种方法,通过标准的c++函数,或者通过某种管理器类,来捕获库崩溃并适当地处理它?"

对于你的问题,我能想到的最简洁的回答是:

坚持使用 c++标准错误处理的类和类别。


当您要求atexit()时,行为在标准参考中也有很好的定义。

注意还有像std::terminate_handler这样的处理程序机制,允许您以可移植和标准兼容的方式处理一些异常的中止情况。

最后但并非最不重要的,它可能需要安装某些(操作系统特定的)信号处理程序,以赶上错误,如所谓的分割故障 (SIGSEV)由于堆栈溢出或类似的事情。

所以我想我的TL;DR问题是:有没有一种方法,要么通过标准的c++函数,或者通过某种管理器类来捕获当库崩溃并适当处理它时?

在结构化异常处理和各种分段错误和总线错误(标准没有提到这些事情)的情况下,防止库崩溃导致用户应用程序崩溃的唯一方法是通过客户端程序执行的二进制文件提供库,并让客户端负责监控客户端进程是否死亡。

如果您希望库直接链接到用户的应用程序,那么您无法做来绝对确保库中的错误不会使用户的应用程序崩溃。这就是单元、子系统和系统测试套件的作用。请记住,如果你的库崩溃了一个应用程序,我所知道的几乎每个操作系统都会回收它分配的所有资源,所以你不需要一个全局单例来释放堆内存:它会在崩溃时自动被操作系统占用。

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