繁体   English   中英

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

[英]Keep running the program after SIGABRT c++ signal

我在我的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或计算机资源(例如内存不足)引起的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM