diff options
Diffstat (limited to 'libgo/go/runtime/panic.go')
-rw-r--r-- | libgo/go/runtime/panic.go | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go index 9667181..88c598e 100644 --- a/libgo/go/runtime/panic.go +++ b/libgo/go/runtime/panic.go @@ -50,7 +50,7 @@ import ( // pc should be the program counter of the compiler-generated code that // triggered this panic. func panicCheck1(pc uintptr, msg string) { - name, _, _, _ := funcfileline(pc-1, -1) + name, _, _, _ := funcfileline(pc-1, -1, false) if hasPrefix(name, "runtime.") { throw(msg) } @@ -548,6 +548,14 @@ func Goexit() { // for detailed comments. gp := getg() gp.goexiting = true + + // Create a panic object for Goexit, so we can recognize when it might be + // bypassed by a recover(). + var p _panic + p.goexit = true + p.link = gp._panic + gp._panic = (*_panic)(noescape(unsafe.Pointer(&p))) + for { d := gp._defer if d == nil { @@ -608,7 +616,12 @@ func preprintpanics(p *_panic) { func printpanics(p *_panic) { if p.link != nil { printpanics(p.link) - print("\t") + if !p.link.goexit { + print("\t") + } + } + if p.goexit { + return } print("panic: ") printany(p.arg) @@ -704,9 +717,12 @@ func gopanic(e interface{}) { d._panic = nil if p.recovered { - atomic.Xadd(&runningPanicDefers, -1) - gp._panic = p.link + if gp._panic != nil && gp._panic.goexit && gp._panic.aborted { + Goexit() + throw("Goexit returned") + } + atomic.Xadd(&runningPanicDefers, -1) // Aborted panics are marked but remain on the g.panic list. // Remove them from the list. @@ -717,6 +733,11 @@ func gopanic(e interface{}) { gp.sig = 0 } + if gp._panic != nil && gp._panic.goexit { + Goexit() + throw("Goexit returned") + } + // Unwind the stack by throwing an exception. // The compiler has arranged to create // exception handlers in each function @@ -922,7 +943,7 @@ func makefuncreturning() { func gorecover() interface{} { gp := getg() p := gp._panic - if p != nil && !p.recovered { + if p != nil && !p.goexit && !p.recovered { p.recovered = true return p.arg } |