5
的signal package状态:处理与恢复SIGSEGV?
同步信号是由错误的程序 执行触发信号:SIGBUS,SIGFPE和SIGSEGV。使用 os.Process.Kill或杀程序或一些类似的机制发送时由程序执行时引起,而不是这些仅被认为 同步。一般而言,除了下面讨论的外,Go程序会将同步信号转换为运行时间恐慌。
但是,看起来recover()
没有捕捉到这一点。
计划:
package main
import (
"fmt"
"unsafe"
"log"
)
func seeAnotherDay() {
defer func() {
if p := recover(); p != nil {
err := fmt.Errorf("recover panic: panic call")
log.Println(err)
return
}
}()
panic("oops")
}
func notSoMuch() {
defer func() {
if p := recover(); p != nil {
err := fmt.Errorf("recover panic: sigseg")
log.Println(err)
return
}
}()
b := make([]byte, 1)
log.Println("access some memory")
foo := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(9999999999999999)))
fmt.Print(*foo + 1)
}
func main() {
seeAnotherDay()
notSoMuch()
}
输出:
2017/04/04 12:13:16 recover panic: panic call
2017/04/04 12:13:16 access some memory
unexpected fault address 0xb01dfacedebac1e
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x108aa8a]
goroutine 1 [running]:
runtime.throw(0x10b5807, 0x5)
/usr/local/go/src/runtime/panic.go:596 +0x95 fp=0xc420043ea8 sp=0xc420043e88
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:297 +0x28c fp=0xc420043ef8 sp=0xc420043ea8
main.notSoMuch()
/Users/kbrandt/src/sigseg/main.go:32 +0xca fp=0xc420043f78 sp=0xc420043ef8
main.main()
/Users/kbrandt/src/sigseg/main.go:37 +0x25 fp=0xc420043f88 sp=0xc420043f78
runtime.main()
/usr/local/go/src/runtime/proc.go:185 +0x20a fp=0xc420043fe0 sp=0xc420043f88
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc420043fe8 sp=0xc420043fe0
exit status 2
有什么办法,我可以在本地化的代码的某些部分的方式处理SIGSEGV?
在“为什么你要做到这一点,这似乎nutso”条款是在我的系统用户可以创建模板。我想保护主运行时免受渲染模板时生成的任何错误。真实世界的问题在github上[这里](https://github.com/bosun-monitor/bosun/issues/2054)。 –
与Gopher中的人闲聊的想法似乎是sigsegv将程序置于未定义状态,无法从安全中恢复。 –
您无法从“致命错误”中恢复,这不是“恐慌” – JimB