在SIGABRT c ++信号之后继续运行程序

Keep running the program after SIGABRT c++ signal

本文关键字:继续 运行 程序 之后 信号 SIGABRT      更新时间:2023-10-16

我在c ++程序中使用第三个库,在某些情况下会发出SIGABRT信号。我知道尝试释放未初始化的指针或类似的东西可能是此信号的原因。尽管如此,我想在发出此信号后继续运行我的程序,以显示一条消息并允许用户更改设置,以应对此信号。
(我使用QT进行开发。

我该怎么做?

我在 c++ 程序中使用了第三个库,在某些情况下会发出 SIGABRT 信号

如果您有该库的源代码,则需要更正错误(并且错误可能在您的代码中)。

顺便说一句,SIGABRT发生可能是因为 abort(3) 被间接调用(可能是因为你违反了该库的某些约定或不变量,它可能使用 assert(3) - 并间接调用abort)。我猜在 caffe 中,各种CHECK*宏可以间接调用abort.我让你去调查一下。

如果您没有源代码,或者没有能力或时间来修复该第三方库中的错误,则应放弃使用该库并使用其他内容。

在许多情况下,您应该信任外部库而不是您自己的代码。您可能正在滥用或误用该库。仔细阅读其文档,并确保调用它自己的代码正确使用该库并遵守其不变量和约定。该错误可能在您自己的代码中,在其他地方。

我想继续运行我的程序

这是不可能的(或者非常不可靠,所以不合理)。我猜你的程序有一些未定义的行为非常害怕,并努力避免UB。

您需要提高调试技能。更好地学习如何使用gdb调试器、valgrind、GCC 消毒器(例如-fsanitize=address-fsanitize=undefined等检测选项)等......

你合理地不应该尝试处理SIGABRT即使原则上你可以(但随后仔细阅读signal(7),signal-safety(7)和关于在Qt中处理Unix信号的提示)。我强烈建议甚至避免尝试抓住SIGABRT

不幸的是,你不能。SIGABRT 信号本身在 abort() 之后立即发送

裁判: https://stackoverflow.com/a/3413215/9332965

你可以处理SIGABRT,但你可能不应该


"罐头"很简单 - 只需使用signal()以通常的方式捕获它. 您不想从此信号处理程序返回 - 您可能从abort()到达此处 - 可能最初来自assert()- 并且该函数将在发出信号后退出。 但是,您可以longjmp()恢复到之前设置的状态。


"不应该"是因为一旦SIGABRT被提出,你的数据结构(包括Qt和任何其他库的数据结构)可能处于不一致的状态,并且实际使用你的程序的任何状态充其量可能是不可预测的。 除了立即退出之外,除了exec()替换程序以在理智的初始状态下接管之外,您无能为力。

如果您只想显示友好的消息,那么也许可以exec()一个小程序来执行此操作(或仅使用xmessage),但请注意以成功状态退出它,否则您将有SIGABRT指示。

不幸的是,你没有太多办法来阻止SIGABRT终止你的程序。并非没有修改一些希望由您编写的代码。

您要么需要更改代码以不引发中止,要么必须生成运行代码而不是当前进程的新进程。我不建议您使用子进程来解决此问题。这很可能是由滥用 API 或计算机资源(如内存不足)引起的。