7

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

4

3 回答 3

17

请注意,它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 以及其他平台上运行,尽管您在中止处理程序中所做的通常是不可移植的。请注意,此处理程序也会在assert失败时调用,甚至由其他运行时函数调用 - 例如,如果malloc检测到堆损坏。因此,您的程序可能在该处理程序期间处于疯狂状态。您不应该分配内存 - 如果可能,请使用静态缓冲区。只需做最少的事情来收集您需要的信息,向用户发送错误消息,然后退出。

Certain platforms may allow their abort functions to be customized further. For example, on Windows, Visual C++ has a function _set_abort_behavior that lets you choose whether or not a message is displayed to the user, and whether crash dumps are collected.

于 2010-10-12T01:29:58.203 回答
3

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

于 2010-10-12T00:55:03.227 回答
0

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

于 2010-10-12T00:29:51.007 回答