2

我环顾了不同的站点,除了那些似乎不起作用的站点之外,找不到这个问题的任何答案。正如标题所说,我正试图找到一种方法来捕捉我正在处理的库是否崩溃。我有一个 Root 类,其中包含我在库中拥有的许多管理器样式类的实例,并且它在其析构函数中释放实例。当然,管理人员要对相当多的数据负责,因此如果没有妥善处理这些数据,就有可能出现相当不可接受甚至危险的内存泄漏水平。

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

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

所以我想我的 TL;DR 问题是这样的:有没有办法通过标准的 C++ 函数或某种管理器类来捕捉库何时崩溃并适当地处理它?

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

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

4

2 回答 2

2

“有没有办法,或者通过标准的 C++ 函数,或者通过某种管理器类,来捕捉库何时崩溃并适当地处理它?”

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

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


正如您所要求的atexit(),该行为在标准参考中也得到了很好的定义。

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

最后但并非最不重要的一点是,可能需要安装某些(特定于操作系统的)信号处理程序,以赶上错误,例如由于堆栈溢出或类似情况而引发的所谓的分段错误。 (SIGSEV)

于 2014-08-05T19:01:29.223 回答
1

所以我想我的 TL;DR 问题是这样的:有没有办法通过标准的 C++ 函数或某种管理器类来捕捉库何时崩溃并适当地处理它?

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

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

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

于 2014-08-05T19:39:16.877 回答