如何解决CGO:处理 SIGTERM / SIGABRT
我正在调用在许多地方使用 a 的 assert c 库。这对我来说是个问题,因为我不希望我的应用程序在断言失败时终止。
设置 NDEBUG
标志以禁用断言无济于事,因为它只会导致段错误。
这是我目前得到的,但未捕获到 SIGTERM。
// Redefine the MPE_Assert macro to use SIGTERM since SIGABRT cannot be stopped.
// #include <signal.h>
// #define MPE_Assert(_Expression) (void) ((!!(_Expression)) || (raise(SIGTERM)))
import "C"
func Poly2Tri(verts [][2]float32,holes [][][2]float32) [][2]float32 {
sig := make(chan os.Signal,10)
result := make(chan [][2]float32)
defer signal.Stop(sig)
go func() {
// Notify for all signals
signal.Notify(sig)
result <- poly2Tri(verts,holes)
}()
select {
case res := <-result:
return res
case <-sig:
return [][2]float32{}
}
}
那么,如何在断言失败时允许库退出但允许我的应用程序继续?
我不认为 poly2Tri
函数与此问题相关,但如果需要,我可以添加它。
解决方法
可以在原生 Go 代码中使用 signal.Notify
或在 C 中使用 sigaction
(可能通过 cgo 调用设置)来处理 SIGTERM
和 SIGABRT
。
然而,SIGTERM
或 SIGABRT
处理程序应该不阻止进程终止——它可以做一些尽力而为的日志记录(也许有助于调试),或者刷新中间输出(以减少丢失的工作量),但通常 assert
失败可能表明程序以某种方式严重损坏 - 如果它继续运行,它可能会产生任意错误的输出(例如由于内存损坏),或段错误(因为程序不希望对 assert
的调用返回),或死锁(因为 assert
表示已损坏的锁定不变式)。
如果您在遇到 assert
次失败的程序时遇到问题,与其试图捕获和抑制这些失败,不如寻找重现它们的方法(例如通过 {{3} } 您的程序的输入,或记录程序在失败前正在执行的操作的痕迹)。然后,您可以修复 assert
失败的根本原因,而无需尝试从中恢复。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。