summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/panic1.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/panic1.go')
-rw-r--r--src/pkg/runtime/panic1.go209
1 files changed, 0 insertions, 209 deletions
diff --git a/src/pkg/runtime/panic1.go b/src/pkg/runtime/panic1.go
deleted file mode 100644
index e87743432..000000000
--- a/src/pkg/runtime/panic1.go
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import "unsafe"
-
-// Print all currently active panics. Used when crashing.
-func printpanics(p *_panic) {
- if p.link != nil {
- printpanics(p.link)
- print("\t")
- }
- print("panic: ")
- printany(p.arg)
- if p.recovered {
- print(" [recovered]")
- }
- print("\n")
-}
-
-// The implementation of the predeclared function panic.
-func gopanic(e interface{}) {
- gp := getg()
- if gp.m.curg != gp {
- gothrow("panic on m stack")
- }
- var p _panic
- var dabort _defer
- p.arg = e
- p.link = gp._panic
- gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
-
- fn := abortpanic
- dabort.fn = *(**funcval)(unsafe.Pointer(&fn))
- dabort.siz = ptrSize
- dabort.args[0] = noescape((unsafe.Pointer)(&p)) // TODO(khr): why do I need noescape here?
- dabort.argp = _NoArgs
- dabort.special = true
-
- for {
- d := gp._defer
- if d == nil {
- break
- }
- // take defer off list in case of recursive panic
- gp._defer = d.link
- argp := unsafe.Pointer(d.argp) // must be pointer so it gets adjusted during stack copy
- pc := d.pc
-
- // The deferred function may cause another panic,
- // so reflectcall may not return. Set up a defer
- // to mark this panic aborted if that happens.
- dabort.link = gp._defer
- gp._defer = (*_defer)(noescape(unsafe.Pointer(&dabort)))
- p._defer = d
-
- p.argp = getargp(0)
- reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz))
- p.argp = 0
-
- // reflectcall did not panic. Remove dabort.
- if gp._defer != &dabort {
- gothrow("bad defer entry in panic")
- }
- gp._defer = dabort.link
-
- // trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic
- //GC()
-
- freedefer(d)
- if p.recovered {
- gp._panic = p.link
- // Aborted panics are marked but remain on the g.panic list.
- // Remove them from the list and free the associated defers.
- for gp._panic != nil && gp._panic.aborted {
- freedefer(gp._panic._defer)
- gp._panic = gp._panic.link
- }
- if gp._panic == nil { // must be done with signal
- gp.sig = 0
- }
- // Pass information about recovering frame to recovery.
- gp.sigcode0 = uintptr(argp)
- gp.sigcode1 = pc
- mcall(recovery_m)
- gothrow("recovery failed") // mcall should not return
- }
- }
-
- // ran out of deferred calls - old-school panic now
- startpanic()
- printpanics(gp._panic)
- dopanic(0) // should not return
- *(*int)(nil) = 0 // not reached
-}
-
-// getargp returns the location where the caller
-// writes outgoing function call arguments.
-//go:nosplit
-func getargp(x int) uintptr {
- // x is an argument mainly so that we can return its address.
- // However, we need to make the function complex enough
- // that it won't be inlined. We always pass x = 0, so this code
- // does nothing other than keep the compiler from thinking
- // the function is simple enough to inline.
- if x > 0 {
- return getcallersp(unsafe.Pointer(&x)) * 0
- }
- return uintptr(noescape(unsafe.Pointer(&x)))
-}
-
-func abortpanic(p *_panic) {
- p.aborted = true
-}
-
-// The implementation of the predeclared function recover.
-// Cannot split the stack because it needs to reliably
-// find the stack segment of its caller.
-//
-// TODO(rsc): Once we commit to CopyStackAlways,
-// this doesn't need to be nosplit.
-//go:nosplit
-func gorecover(argp uintptr) interface{} {
- // Must be in a function running as part of a deferred call during the panic.
- // Must be called from the topmost function of the call
- // (the function used in the defer statement).
- // p.argp is the argument pointer of that topmost deferred function call.
- // Compare against argp reported by caller.
- // If they match, the caller is the one who can recover.
- gp := getg()
- p := gp._panic
- if p != nil && !p.recovered && argp == p.argp {
- p.recovered = true
- return p.arg
- }
- return nil
-}
-
-//go:nosplit
-func startpanic() {
- onM(startpanic_m)
-}
-
-//go:nosplit
-func dopanic(unused int) {
- gp := getg()
- mp := acquirem()
- mp.ptrarg[0] = unsafe.Pointer(gp)
- mp.scalararg[0] = getcallerpc((unsafe.Pointer)(&unused))
- mp.scalararg[1] = getcallersp((unsafe.Pointer)(&unused))
- onM(dopanic_m) // should never return
- *(*int)(nil) = 0
-}
-
-//go:nosplit
-func throw(s *byte) {
- gp := getg()
- if gp.m.throwing == 0 {
- gp.m.throwing = 1
- }
- startpanic()
- print("fatal error: ", gostringnocopy(s), "\n")
- dopanic(0)
- *(*int)(nil) = 0 // not reached
-}
-
-//go:nosplit
-func gothrow(s string) {
- gp := getg()
- if gp.m.throwing == 0 {
- gp.m.throwing = 1
- }
- startpanic()
- print("fatal error: ", s, "\n")
- dopanic(0)
- *(*int)(nil) = 0 // not reached
-}
-
-func panicstring(s *int8) {
- // m.softfloat is set during software floating point,
- // which might cause a fault during a memory load.
- // It increments m.locks to avoid preemption.
- // If we're panicking, the software floating point frames
- // will be unwound, so decrement m.locks as they would.
- gp := getg()
- if gp.m.softfloat != 0 {
- gp.m.locks--
- gp.m.softfloat = 0
- }
-
- if gp.m.mallocing != 0 {
- print("panic: ", s, "\n")
- gothrow("panic during malloc")
- }
- if gp.m.gcing != 0 {
- print("panic: ", s, "\n")
- gothrow("panic during gc")
- }
- if gp.m.locks != 0 {
- print("panic: ", s, "\n")
- gothrow("panic holding locks")
- }
-
- var err interface{}
- newErrorCString(unsafe.Pointer(s), &err)
- gopanic(err)
-}