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