[英]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()之后立即发送
您可以处理SIGABRT
,但您可能不应该这样做 。
“罐头”很简单-使用signal()
以通常的方式捕获它。 您不想从该信号处理程序中返回-您可能是从abort()
到达这里的-可能最初是从assert()
到达的-并且该函数将在引发信号后退出。 但是,您可以将longjmp()
恢复为之前设置的状态。
“不应该”是因为一旦引发了SIGABRT
,您的数据结构(包括Qt和任何其他库的数据结构)可能处于不一致状态,而实际上使用程序的任何状态充其量都是不可预测的。 除了立即退出之外,除了exec()
替换程序可以在健全的初始状态下接管之外,您无能为力。
如果您只想显示一条友好的消息,则可以exec()
一个小程序来执行此操作(或仅使用xmessage
),但是请注意,不要以成功状态退出该状态,否则将显示SIGABRT
。
不幸的是,您没有什么可以阻止SIGABRT终止程序的。 并非没有修改您希望编写的某些代码。
您可能需要更改代码以不中止操作,或者必须生成一个运行该代码的新进程而不是当前进程。 我不建议您使用子进程来解决此问题。 这很可能是由于滥用api或计算机资源(例如内存不足)引起的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.