The signal packet indicates:
Synchronous signals are signals caused by errors in the execution program: SIGBUS, SIGFPE and SIGSEGV. They are considered only synchronously when triggered by the execution of a program, and not when sent using os.Process.Kill or a kill program or similar mechanism. In general, with the exception of the cases discussed below, Go programs convert a synchronous signal during a pause.
However, it seems that recover() does not understand this.
Program:
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() }
Output:
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
Is there any way to handle SIGSEGV so that it is localized in certain parts of the code?
source share