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