c++ 中止覆盖

Posted

技术标签:

【中文标题】c++ 中止覆盖【英文标题】:c++ abort override 【发布时间】:2010-10-12 00:16:44 【问题描述】:

一些 C++ 库在出错的情况下调用 abort() 函数(例如,SDL)。在这种情况下,没有提供有用的调试信息。无法捕获中止调用并写入一些诊断日志输出。我想在不重写/重建这些库的情况下全局覆盖此行为。我想抛出异常并处理它。有可能吗?

【问题讨论】:

【参考方案1】:

请注意,abort 引发了SIGABRT 信号,就好像它调用了raise(SIGABRT)。您可以安装在这种情况下调用的信号处理程序,如下所示:

#include <signal.h>

extern "C" void my_function_to_handle_aborts(int signal_number)

    /*Your code goes here. You can output debugging info.
      If you return from this function, and it was called 
      because abort() was called, your program will exit or crash anyway
      (with a dialog box on Windows).
     */


/*Do this early in your program's initialization */
signal(SIGABRT, &my_function_to_handle_aborts);

如果您无法阻止abort 调用(例如,尽管您的意图是好的,但它们是由于错误潜入),这可能允许您收集更多调试信息。这是可移植的 ANSI C,因此它也可以在 Unix 和 Windows 以及其他平台上运行,尽管您在 abort 处理程序中执行的操作通常是不可移植的。请注意,当 assert 失败时,甚至由其他运行时函数调用此处理程序 - 例如,如果 malloc 检测到堆损坏。因此,您的程序可能在该处理程序期间处于疯狂状态。您不应该分配内存 - 如果可能,请使用静态缓冲区。只需做最低限度的工作即可收集您需要的信息,向用户发送错误消息,然后退出。

某些平台可能允许进一步自定义其abort 函数。例如,在 Windows 上,Visual C++ 有一个函数_set_abort_behavior,让您可以选择是否向用户显示消息,以及是否收集故障转储。

【讨论】:

如果 my_function_to_handle_aborts 抛出怎么办? ) @Pavel:它是实现定义的,即不可移植。基本上,您可以保证能够使用 C 的功能,但您可能无法使用 C++ 功能,例如声明变量、调用newdelete 或抛出异常。不过,在许多实现中,它可能会起作用。此外,该函数应该具有 C 链接 - 我已经编辑了答案,但它不太可能在 Windows 或 Unix 上有所作为。 您会在处理函数中添加什么来显示导致错误的原因? gdb 会在该函数中遇到断点并显示有效的堆栈跟踪吗?"【参考方案2】:

根据 Linux 上的手册页,abort() 为可以被信号处理程序捕获的进程生成一个 SIGABRT。编辑:Ben 确认这在 Windows 上也是可能的 - 请参阅下面的评论。

【讨论】:

Visual C++ 的 abort 函数也是如此。 void abort() - 通过引发 SIGABRT 中止当前程序 目的:打印出中止消息并引发 SIGABRT 信号。如果用户还没有定义中止处理程序例程,则以退出状态 3 终止程序而不进行清理。【参考方案3】:

您可以尝试自己编写并让链接器调用您的链接器来代替 std::abort。不过,我不确定这是否可能。

【讨论】:

以上是关于c++ 中止覆盖的主要内容,如果未能解决你的问题,请参考以下文章

C++ 实现子类扩展子接口而不覆盖已经覆盖的方法

C++:覆盖公共\私有继承

LCOV/GCOV 分支覆盖,C++ 生成分支遍布各处

覆盖向量 C++

c++ 函数的隐藏和覆盖

C++ 覆盖引号