CGO:交易 SIGTERM / SIGABRT
CGO: handle SIGTERM / SIGABRT
我在很多地方打电话给a c library that uses assert。这对我来说是个问题,因为我不希望我的应用程序在断言失败时终止。
设置 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
函数与此问题无关,但如果需要我可以添加它。
可以在 C 中使用 signal.Notify
in native Go code or sigaction
处理 SIGTERM
和 SIGABRT
(可能通过 cgo 调用设置)。
但是,SIGTERM
或 SIGABRT
处理程序应该 而不是 阻止进程终止 — 它可以做一些尽力而为的日志记录(也许是为了帮助在调试中),或刷新中间输出(以减少丢失的工作量),但通常 assert
失败可能表明程序在某种程度上严重损坏 — 如果它继续 运行,它可能会产生任意错误的输出(例如由于内存损坏),或段错误(因为程序不希望调用 assert
到 return),或死锁(因为 assert
表明一个损坏的锁定不变量)。
如果您在处理 运行 导致 assert
故障的程序时遇到问题,与其试图捕获和抑制这些故障,不如寻找重现它们的方法(例如通过 fuzzing 您程序的输入,或记录失败前程序正在执行的操作)。然后您可以修复 assert
故障的根本原因,并且您无需尝试从中恢复。
我在很多地方打电话给a c library that uses assert。这对我来说是个问题,因为我不希望我的应用程序在断言失败时终止。
设置 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
函数与此问题无关,但如果需要我可以添加它。
可以在 C 中使用 signal.Notify
in native Go code or sigaction
处理 SIGTERM
和 SIGABRT
(可能通过 cgo 调用设置)。
但是,SIGTERM
或 SIGABRT
处理程序应该 而不是 阻止进程终止 — 它可以做一些尽力而为的日志记录(也许是为了帮助在调试中),或刷新中间输出(以减少丢失的工作量),但通常 assert
失败可能表明程序在某种程度上严重损坏 — 如果它继续 运行,它可能会产生任意错误的输出(例如由于内存损坏),或段错误(因为程序不希望调用 assert
到 return),或死锁(因为 assert
表明一个损坏的锁定不变量)。
如果您在处理 运行 导致 assert
故障的程序时遇到问题,与其试图捕获和抑制这些故障,不如寻找重现它们的方法(例如通过 fuzzing 您程序的输入,或记录失败前程序正在执行的操作)。然后您可以修复 assert
故障的根本原因,并且您无需尝试从中恢复。