Home | History | Annotate | Download | only in runtime
      1 // Copyright 2014 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package runtime
      6 
      7 import (
      8 	"runtime/internal/atomic"
      9 	"runtime/internal/sys"
     10 	"unsafe"
     11 )
     12 
     13 // Calling panic with one of the errors below will call errorString.Error
     14 // which will call mallocgc to concatenate strings. That will fail if
     15 // malloc is locked, causing a confusing error message. Throw a better
     16 // error message instead.
     17 func panicCheckMalloc(err error) {
     18 	gp := getg()
     19 	if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
     20 		throw(string(err.(errorString)))
     21 	}
     22 }
     23 
     24 var indexError = error(errorString("index out of range"))
     25 
     26 func panicindex() {
     27 	panicCheckMalloc(indexError)
     28 	panic(indexError)
     29 }
     30 
     31 var sliceError = error(errorString("slice bounds out of range"))
     32 
     33 func panicslice() {
     34 	panicCheckMalloc(sliceError)
     35 	panic(sliceError)
     36 }
     37 
     38 var divideError = error(errorString("integer divide by zero"))
     39 
     40 func panicdivide() {
     41 	panicCheckMalloc(divideError)
     42 	panic(divideError)
     43 }
     44 
     45 var overflowError = error(errorString("integer overflow"))
     46 
     47 func panicoverflow() {
     48 	panicCheckMalloc(overflowError)
     49 	panic(overflowError)
     50 }
     51 
     52 var floatError = error(errorString("floating point error"))
     53 
     54 func panicfloat() {
     55 	panicCheckMalloc(floatError)
     56 	panic(floatError)
     57 }
     58 
     59 var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
     60 
     61 func panicmem() {
     62 	panicCheckMalloc(memoryError)
     63 	panic(memoryError)
     64 }
     65 
     66 func throwinit() {
     67 	throw("recursive call during initialization - linker skew")
     68 }
     69 
     70 // Create a new deferred function fn with siz bytes of arguments.
     71 // The compiler turns a defer statement into a call to this.
     72 //go:nosplit
     73 func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
     74 	if getg().m.curg != getg() {
     75 		// go code on the system stack can't defer
     76 		throw("defer on system stack")
     77 	}
     78 
     79 	// the arguments of fn are in a perilous state. The stack map
     80 	// for deferproc does not describe them. So we can't let garbage
     81 	// collection or stack copying trigger until we've copied them out
     82 	// to somewhere safe. The memmove below does that.
     83 	// Until the copy completes, we can only call nosplit routines.
     84 	sp := getcallersp(unsafe.Pointer(&siz))
     85 	argp := uintptr(unsafe.Pointer(&fn)) + unsafe.Sizeof(fn)
     86 	callerpc := getcallerpc()
     87 
     88 	d := newdefer(siz)
     89 	if d._panic != nil {
     90 		throw("deferproc: d.panic != nil after newdefer")
     91 	}
     92 	d.fn = fn
     93 	d.pc = callerpc
     94 	d.sp = sp
     95 	switch siz {
     96 	case 0:
     97 		// Do nothing.
     98 	case sys.PtrSize:
     99 		*(*uintptr)(deferArgs(d)) = *(*uintptr)(unsafe.Pointer(argp))
    100 	default:
    101 		memmove(deferArgs(d), unsafe.Pointer(argp), uintptr(siz))
    102 	}
    103 
    104 	// deferproc returns 0 normally.
    105 	// a deferred func that stops a panic
    106 	// makes the deferproc return 1.
    107 	// the code the compiler generates always
    108 	// checks the return value and jumps to the
    109 	// end of the function if deferproc returns != 0.
    110 	return0()
    111 	// No code can go here - the C return register has
    112 	// been set and must not be clobbered.
    113 }
    114 
    115 // Small malloc size classes >= 16 are the multiples of 16: 16, 32, 48, 64, 80, 96, 112, 128, 144, ...
    116 // Each P holds a pool for defers with small arg sizes.
    117 // Assign defer allocations to pools by rounding to 16, to match malloc size classes.
    118 
    119 const (
    120 	deferHeaderSize = unsafe.Sizeof(_defer{})
    121 	minDeferAlloc   = (deferHeaderSize + 15) &^ 15
    122 	minDeferArgs    = minDeferAlloc - deferHeaderSize
    123 )
    124 
    125 // defer size class for arg size sz
    126 //go:nosplit
    127 func deferclass(siz uintptr) uintptr {
    128 	if siz <= minDeferArgs {
    129 		return 0
    130 	}
    131 	return (siz - minDeferArgs + 15) / 16
    132 }
    133 
    134 // total size of memory block for defer with arg size sz
    135 func totaldefersize(siz uintptr) uintptr {
    136 	if siz <= minDeferArgs {
    137 		return minDeferAlloc
    138 	}
    139 	return deferHeaderSize + siz
    140 }
    141 
    142 // Ensure that defer arg sizes that map to the same defer size class
    143 // also map to the same malloc size class.
    144 func testdefersizes() {
    145 	var m [len(p{}.deferpool)]int32
    146 
    147 	for i := range m {
    148 		m[i] = -1
    149 	}
    150 	for i := uintptr(0); ; i++ {
    151 		defersc := deferclass(i)
    152 		if defersc >= uintptr(len(m)) {
    153 			break
    154 		}
    155 		siz := roundupsize(totaldefersize(i))
    156 		if m[defersc] < 0 {
    157 			m[defersc] = int32(siz)
    158 			continue
    159 		}
    160 		if m[defersc] != int32(siz) {
    161 			print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
    162 			throw("bad defer size class")
    163 		}
    164 	}
    165 }
    166 
    167 // The arguments associated with a deferred call are stored
    168 // immediately after the _defer header in memory.
    169 //go:nosplit
    170 func deferArgs(d *_defer) unsafe.Pointer {
    171 	if d.siz == 0 {
    172 		// Avoid pointer past the defer allocation.
    173 		return nil
    174 	}
    175 	return add(unsafe.Pointer(d), unsafe.Sizeof(*d))
    176 }
    177 
    178 var deferType *_type // type of _defer struct
    179 
    180 func init() {
    181 	var x interface{}
    182 	x = (*_defer)(nil)
    183 	deferType = (*(**ptrtype)(unsafe.Pointer(&x))).elem
    184 }
    185 
    186 // Allocate a Defer, usually using per-P pool.
    187 // Each defer must be released with freedefer.
    188 //
    189 // This must not grow the stack because there may be a frame without
    190 // stack map information when this is called.
    191 //
    192 //go:nosplit
    193 func newdefer(siz int32) *_defer {
    194 	var d *_defer
    195 	sc := deferclass(uintptr(siz))
    196 	gp := getg()
    197 	if sc < uintptr(len(p{}.deferpool)) {
    198 		pp := gp.m.p.ptr()
    199 		if len(pp.deferpool[sc]) == 0 && sched.deferpool[sc] != nil {
    200 			// Take the slow path on the system stack so
    201 			// we don't grow newdefer's stack.
    202 			systemstack(func() {
    203 				lock(&sched.deferlock)
    204 				for len(pp.deferpool[sc]) < cap(pp.deferpool[sc])/2 && sched.deferpool[sc] != nil {
    205 					d := sched.deferpool[sc]
    206 					sched.deferpool[sc] = d.link
    207 					d.link = nil
    208 					pp.deferpool[sc] = append(pp.deferpool[sc], d)
    209 				}
    210 				unlock(&sched.deferlock)
    211 			})
    212 		}
    213 		if n := len(pp.deferpool[sc]); n > 0 {
    214 			d = pp.deferpool[sc][n-1]
    215 			pp.deferpool[sc][n-1] = nil
    216 			pp.deferpool[sc] = pp.deferpool[sc][:n-1]
    217 		}
    218 	}
    219 	if d == nil {
    220 		// Allocate new defer+args.
    221 		systemstack(func() {
    222 			total := roundupsize(totaldefersize(uintptr(siz)))
    223 			d = (*_defer)(mallocgc(total, deferType, true))
    224 		})
    225 	}
    226 	d.siz = siz
    227 	d.link = gp._defer
    228 	gp._defer = d
    229 	return d
    230 }
    231 
    232 // Free the given defer.
    233 // The defer cannot be used after this call.
    234 //
    235 // This must not grow the stack because there may be a frame without a
    236 // stack map when this is called.
    237 //
    238 //go:nosplit
    239 func freedefer(d *_defer) {
    240 	if d._panic != nil {
    241 		freedeferpanic()
    242 	}
    243 	if d.fn != nil {
    244 		freedeferfn()
    245 	}
    246 	sc := deferclass(uintptr(d.siz))
    247 	if sc >= uintptr(len(p{}.deferpool)) {
    248 		return
    249 	}
    250 	pp := getg().m.p.ptr()
    251 	if len(pp.deferpool[sc]) == cap(pp.deferpool[sc]) {
    252 		// Transfer half of local cache to the central cache.
    253 		//
    254 		// Take this slow path on the system stack so
    255 		// we don't grow freedefer's stack.
    256 		systemstack(func() {
    257 			var first, last *_defer
    258 			for len(pp.deferpool[sc]) > cap(pp.deferpool[sc])/2 {
    259 				n := len(pp.deferpool[sc])
    260 				d := pp.deferpool[sc][n-1]
    261 				pp.deferpool[sc][n-1] = nil
    262 				pp.deferpool[sc] = pp.deferpool[sc][:n-1]
    263 				if first == nil {
    264 					first = d
    265 				} else {
    266 					last.link = d
    267 				}
    268 				last = d
    269 			}
    270 			lock(&sched.deferlock)
    271 			last.link = sched.deferpool[sc]
    272 			sched.deferpool[sc] = first
    273 			unlock(&sched.deferlock)
    274 		})
    275 	}
    276 
    277 	// These lines used to be simply `*d = _defer{}` but that
    278 	// started causing a nosplit stack overflow via typedmemmove.
    279 	d.siz = 0
    280 	d.started = false
    281 	d.sp = 0
    282 	d.pc = 0
    283 	d.fn = nil
    284 	d._panic = nil
    285 	d.link = nil
    286 
    287 	pp.deferpool[sc] = append(pp.deferpool[sc], d)
    288 }
    289 
    290 // Separate function so that it can split stack.
    291 // Windows otherwise runs out of stack space.
    292 func freedeferpanic() {
    293 	// _panic must be cleared before d is unlinked from gp.
    294 	throw("freedefer with d._panic != nil")
    295 }
    296 
    297 func freedeferfn() {
    298 	// fn must be cleared before d is unlinked from gp.
    299 	throw("freedefer with d.fn != nil")
    300 }
    301 
    302 // Run a deferred function if there is one.
    303 // The compiler inserts a call to this at the end of any
    304 // function which calls defer.
    305 // If there is a deferred function, this will call runtimejmpdefer,
    306 // which will jump to the deferred function such that it appears
    307 // to have been called by the caller of deferreturn at the point
    308 // just before deferreturn was called. The effect is that deferreturn
    309 // is called again and again until there are no more deferred functions.
    310 // Cannot split the stack because we reuse the caller's frame to
    311 // call the deferred function.
    312 
    313 // The single argument isn't actually used - it just has its address
    314 // taken so it can be matched against pending defers.
    315 //go:nosplit
    316 func deferreturn(arg0 uintptr) {
    317 	gp := getg()
    318 	d := gp._defer
    319 	if d == nil {
    320 		return
    321 	}
    322 	sp := getcallersp(unsafe.Pointer(&arg0))
    323 	if d.sp != sp {
    324 		return
    325 	}
    326 
    327 	// Moving arguments around.
    328 	//
    329 	// Everything called after this point must be recursively
    330 	// nosplit because the garbage collector won't know the form
    331 	// of the arguments until the jmpdefer can flip the PC over to
    332 	// fn.
    333 	switch d.siz {
    334 	case 0:
    335 		// Do nothing.
    336 	case sys.PtrSize:
    337 		*(*uintptr)(unsafe.Pointer(&arg0)) = *(*uintptr)(deferArgs(d))
    338 	default:
    339 		memmove(unsafe.Pointer(&arg0), deferArgs(d), uintptr(d.siz))
    340 	}
    341 	fn := d.fn
    342 	d.fn = nil
    343 	gp._defer = d.link
    344 	freedefer(d)
    345 	jmpdefer(fn, uintptr(unsafe.Pointer(&arg0)))
    346 }
    347 
    348 // Goexit terminates the goroutine that calls it. No other goroutine is affected.
    349 // Goexit runs all deferred calls before terminating the goroutine. Because Goexit
    350 // is not a panic, any recover calls in those deferred functions will return nil.
    351 //
    352 // Calling Goexit from the main goroutine terminates that goroutine
    353 // without func main returning. Since func main has not returned,
    354 // the program continues execution of other goroutines.
    355 // If all other goroutines exit, the program crashes.
    356 func Goexit() {
    357 	// Run all deferred functions for the current goroutine.
    358 	// This code is similar to gopanic, see that implementation
    359 	// for detailed comments.
    360 	gp := getg()
    361 	for {
    362 		d := gp._defer
    363 		if d == nil {
    364 			break
    365 		}
    366 		if d.started {
    367 			if d._panic != nil {
    368 				d._panic.aborted = true
    369 				d._panic = nil
    370 			}
    371 			d.fn = nil
    372 			gp._defer = d.link
    373 			freedefer(d)
    374 			continue
    375 		}
    376 		d.started = true
    377 		reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
    378 		if gp._defer != d {
    379 			throw("bad defer entry in Goexit")
    380 		}
    381 		d._panic = nil
    382 		d.fn = nil
    383 		gp._defer = d.link
    384 		freedefer(d)
    385 		// Note: we ignore recovers here because Goexit isn't a panic
    386 	}
    387 	goexit1()
    388 }
    389 
    390 // Call all Error and String methods before freezing the world.
    391 // Used when crashing with panicking.
    392 // This must match types handled by printany.
    393 func preprintpanics(p *_panic) {
    394 	defer func() {
    395 		if recover() != nil {
    396 			throw("panic while printing panic value")
    397 		}
    398 	}()
    399 	for p != nil {
    400 		switch v := p.arg.(type) {
    401 		case error:
    402 			p.arg = v.Error()
    403 		case stringer:
    404 			p.arg = v.String()
    405 		}
    406 		p = p.link
    407 	}
    408 }
    409 
    410 // Print all currently active panics. Used when crashing.
    411 // Should only be called after preprintpanics.
    412 func printpanics(p *_panic) {
    413 	if p.link != nil {
    414 		printpanics(p.link)
    415 		print("\t")
    416 	}
    417 	print("panic: ")
    418 	// Because of preprintpanics, p.arg cannot be an error or
    419 	// stringer, so this won't call into user code.
    420 	printany(p.arg)
    421 	if p.recovered {
    422 		print(" [recovered]")
    423 	}
    424 	print("\n")
    425 }
    426 
    427 // The implementation of the predeclared function panic.
    428 func gopanic(e interface{}) {
    429 	gp := getg()
    430 	if gp.m.curg != gp {
    431 		print("panic: ")
    432 		printany(e)
    433 		print("\n")
    434 		throw("panic on system stack")
    435 	}
    436 
    437 	// m.softfloat is set during software floating point.
    438 	// It increments m.locks to avoid preemption.
    439 	// We moved the memory loads out, so there shouldn't be
    440 	// any reason for it to panic anymore.
    441 	if gp.m.softfloat != 0 {
    442 		gp.m.locks--
    443 		gp.m.softfloat = 0
    444 		throw("panic during softfloat")
    445 	}
    446 	if gp.m.mallocing != 0 {
    447 		print("panic: ")
    448 		printany(e)
    449 		print("\n")
    450 		throw("panic during malloc")
    451 	}
    452 	if gp.m.preemptoff != "" {
    453 		print("panic: ")
    454 		printany(e)
    455 		print("\n")
    456 		print("preempt off reason: ")
    457 		print(gp.m.preemptoff)
    458 		print("\n")
    459 		throw("panic during preemptoff")
    460 	}
    461 	if gp.m.locks != 0 {
    462 		print("panic: ")
    463 		printany(e)
    464 		print("\n")
    465 		throw("panic holding locks")
    466 	}
    467 
    468 	var p _panic
    469 	p.arg = e
    470 	p.link = gp._panic
    471 	gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
    472 
    473 	atomic.Xadd(&runningPanicDefers, 1)
    474 
    475 	for {
    476 		d := gp._defer
    477 		if d == nil {
    478 			break
    479 		}
    480 
    481 		// If defer was started by earlier panic or Goexit (and, since we're back here, that triggered a new panic),
    482 		// take defer off list. The earlier panic or Goexit will not continue running.
    483 		if d.started {
    484 			if d._panic != nil {
    485 				d._panic.aborted = true
    486 			}
    487 			d._panic = nil
    488 			d.fn = nil
    489 			gp._defer = d.link
    490 			freedefer(d)
    491 			continue
    492 		}
    493 
    494 		// Mark defer as started, but keep on list, so that traceback
    495 		// can find and update the defer's argument frame if stack growth
    496 		// or a garbage collection happens before reflectcall starts executing d.fn.
    497 		d.started = true
    498 
    499 		// Record the panic that is running the defer.
    500 		// If there is a new panic during the deferred call, that panic
    501 		// will find d in the list and will mark d._panic (this panic) aborted.
    502 		d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
    503 
    504 		p.argp = unsafe.Pointer(getargp(0))
    505 		reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
    506 		p.argp = nil
    507 
    508 		// reflectcall did not panic. Remove d.
    509 		if gp._defer != d {
    510 			throw("bad defer entry in panic")
    511 		}
    512 		d._panic = nil
    513 		d.fn = nil
    514 		gp._defer = d.link
    515 
    516 		// trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic
    517 		//GC()
    518 
    519 		pc := d.pc
    520 		sp := unsafe.Pointer(d.sp) // must be pointer so it gets adjusted during stack copy
    521 		freedefer(d)
    522 		if p.recovered {
    523 			atomic.Xadd(&runningPanicDefers, -1)
    524 
    525 			gp._panic = p.link
    526 			// Aborted panics are marked but remain on the g.panic list.
    527 			// Remove them from the list.
    528 			for gp._panic != nil && gp._panic.aborted {
    529 				gp._panic = gp._panic.link
    530 			}
    531 			if gp._panic == nil { // must be done with signal
    532 				gp.sig = 0
    533 			}
    534 			// Pass information about recovering frame to recovery.
    535 			gp.sigcode0 = uintptr(sp)
    536 			gp.sigcode1 = pc
    537 			mcall(recovery)
    538 			throw("recovery failed") // mcall should not return
    539 		}
    540 	}
    541 
    542 	// ran out of deferred calls - old-school panic now
    543 	// Because it is unsafe to call arbitrary user code after freezing
    544 	// the world, we call preprintpanics to invoke all necessary Error
    545 	// and String methods to prepare the panic strings before startpanic.
    546 	preprintpanics(gp._panic)
    547 	startpanic()
    548 
    549 	// startpanic set panicking, which will block main from exiting,
    550 	// so now OK to decrement runningPanicDefers.
    551 	atomic.Xadd(&runningPanicDefers, -1)
    552 
    553 	printpanics(gp._panic)
    554 	dopanic(0)       // should not return
    555 	*(*int)(nil) = 0 // not reached
    556 }
    557 
    558 // getargp returns the location where the caller
    559 // writes outgoing function call arguments.
    560 //go:nosplit
    561 //go:noinline
    562 func getargp(x int) uintptr {
    563 	// x is an argument mainly so that we can return its address.
    564 	return uintptr(noescape(unsafe.Pointer(&x)))
    565 }
    566 
    567 // The implementation of the predeclared function recover.
    568 // Cannot split the stack because it needs to reliably
    569 // find the stack segment of its caller.
    570 //
    571 // TODO(rsc): Once we commit to CopyStackAlways,
    572 // this doesn't need to be nosplit.
    573 //go:nosplit
    574 func gorecover(argp uintptr) interface{} {
    575 	// Must be in a function running as part of a deferred call during the panic.
    576 	// Must be called from the topmost function of the call
    577 	// (the function used in the defer statement).
    578 	// p.argp is the argument pointer of that topmost deferred function call.
    579 	// Compare against argp reported by caller.
    580 	// If they match, the caller is the one who can recover.
    581 	gp := getg()
    582 	p := gp._panic
    583 	if p != nil && !p.recovered && argp == uintptr(p.argp) {
    584 		p.recovered = true
    585 		return p.arg
    586 	}
    587 	return nil
    588 }
    589 
    590 //go:nosplit
    591 func startpanic() {
    592 	systemstack(startpanic_m)
    593 }
    594 
    595 //go:nosplit
    596 func dopanic(unused int) {
    597 	pc := getcallerpc()
    598 	sp := getcallersp(unsafe.Pointer(&unused))
    599 	gp := getg()
    600 	systemstack(func() {
    601 		dopanic_m(gp, pc, sp) // should never return
    602 	})
    603 	*(*int)(nil) = 0
    604 }
    605 
    606 //go:linkname sync_throw sync.throw
    607 func sync_throw(s string) {
    608 	throw(s)
    609 }
    610 
    611 //go:nosplit
    612 func throw(s string) {
    613 	print("fatal error: ", s, "\n")
    614 	gp := getg()
    615 	if gp.m.throwing == 0 {
    616 		gp.m.throwing = 1
    617 	}
    618 	startpanic()
    619 	dopanic(0)
    620 	*(*int)(nil) = 0 // not reached
    621 }
    622 
    623 // runningPanicDefers is non-zero while running deferred functions for panic.
    624 // runningPanicDefers is incremented and decremented atomically.
    625 // This is used to try hard to get a panic stack trace out when exiting.
    626 var runningPanicDefers uint32
    627 
    628 // panicking is non-zero when crashing the program for an unrecovered panic.
    629 // panicking is incremented and decremented atomically.
    630 var panicking uint32
    631 
    632 // paniclk is held while printing the panic information and stack trace,
    633 // so that two concurrent panics don't overlap their output.
    634 var paniclk mutex
    635 
    636 // Unwind the stack after a deferred function calls recover
    637 // after a panic. Then arrange to continue running as though
    638 // the caller of the deferred function returned normally.
    639 func recovery(gp *g) {
    640 	// Info about defer passed in G struct.
    641 	sp := gp.sigcode0
    642 	pc := gp.sigcode1
    643 
    644 	// d's arguments need to be in the stack.
    645 	if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
    646 		print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
    647 		throw("bad recovery")
    648 	}
    649 
    650 	// Make the deferproc for this d return again,
    651 	// this time returning 1.  The calling function will
    652 	// jump to the standard return epilogue.
    653 	gp.sched.sp = sp
    654 	gp.sched.pc = pc
    655 	gp.sched.lr = 0
    656 	gp.sched.ret = 1
    657 	gogo(&gp.sched)
    658 }
    659 
    660 // startpanic_m prepares for an unrecoverable panic.
    661 //
    662 // It can have write barriers because the write barrier explicitly
    663 // ignores writes once dying > 0.
    664 //
    665 //go:yeswritebarrierrec
    666 func startpanic_m() {
    667 	_g_ := getg()
    668 	if mheap_.cachealloc.size == 0 { // very early
    669 		print("runtime: panic before malloc heap initialized\n")
    670 	}
    671 	// Disallow malloc during an unrecoverable panic. A panic
    672 	// could happen in a signal handler, or in a throw, or inside
    673 	// malloc itself. We want to catch if an allocation ever does
    674 	// happen (even if we're not in one of these situations).
    675 	_g_.m.mallocing++
    676 
    677 	switch _g_.m.dying {
    678 	case 0:
    679 		_g_.m.dying = 1
    680 		_g_.writebuf = nil
    681 		atomic.Xadd(&panicking, 1)
    682 		lock(&paniclk)
    683 		if debug.schedtrace > 0 || debug.scheddetail > 0 {
    684 			schedtrace(true)
    685 		}
    686 		freezetheworld()
    687 		return
    688 	case 1:
    689 		// Something failed while panicking, probably the print of the
    690 		// argument to panic().  Just print a stack trace and exit.
    691 		_g_.m.dying = 2
    692 		print("panic during panic\n")
    693 		dopanic(0)
    694 		exit(3)
    695 		fallthrough
    696 	case 2:
    697 		// This is a genuine bug in the runtime, we couldn't even
    698 		// print the stack trace successfully.
    699 		_g_.m.dying = 3
    700 		print("stack trace unavailable\n")
    701 		exit(4)
    702 		fallthrough
    703 	default:
    704 		// Can't even print! Just exit.
    705 		exit(5)
    706 	}
    707 }
    708 
    709 var didothers bool
    710 var deadlock mutex
    711 
    712 func dopanic_m(gp *g, pc, sp uintptr) {
    713 	if gp.sig != 0 {
    714 		signame := signame(gp.sig)
    715 		if signame != "" {
    716 			print("[signal ", signame)
    717 		} else {
    718 			print("[signal ", hex(gp.sig))
    719 		}
    720 		print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
    721 	}
    722 
    723 	level, all, docrash := gotraceback()
    724 	_g_ := getg()
    725 	if level > 0 {
    726 		if gp != gp.m.curg {
    727 			all = true
    728 		}
    729 		if gp != gp.m.g0 {
    730 			print("\n")
    731 			goroutineheader(gp)
    732 			traceback(pc, sp, 0, gp)
    733 		} else if level >= 2 || _g_.m.throwing > 0 {
    734 			print("\nruntime stack:\n")
    735 			traceback(pc, sp, 0, gp)
    736 		}
    737 		if !didothers && all {
    738 			didothers = true
    739 			tracebackothers(gp)
    740 		}
    741 	}
    742 	unlock(&paniclk)
    743 
    744 	if atomic.Xadd(&panicking, -1) != 0 {
    745 		// Some other m is panicking too.
    746 		// Let it print what it needs to print.
    747 		// Wait forever without chewing up cpu.
    748 		// It will exit when it's done.
    749 		lock(&deadlock)
    750 		lock(&deadlock)
    751 	}
    752 
    753 	if docrash {
    754 		crash()
    755 	}
    756 
    757 	exit(2)
    758 }
    759 
    760 // canpanic returns false if a signal should throw instead of
    761 // panicking.
    762 //
    763 //go:nosplit
    764 func canpanic(gp *g) bool {
    765 	// Note that g is m->gsignal, different from gp.
    766 	// Note also that g->m can change at preemption, so m can go stale
    767 	// if this function ever makes a function call.
    768 	_g_ := getg()
    769 	_m_ := _g_.m
    770 
    771 	// Is it okay for gp to panic instead of crashing the program?
    772 	// Yes, as long as it is running Go code, not runtime code,
    773 	// and not stuck in a system call.
    774 	if gp == nil || gp != _m_.curg {
    775 		return false
    776 	}
    777 	if _m_.locks-_m_.softfloat != 0 || _m_.mallocing != 0 || _m_.throwing != 0 || _m_.preemptoff != "" || _m_.dying != 0 {
    778 		return false
    779 	}
    780 	status := readgstatus(gp)
    781 	if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
    782 		return false
    783 	}
    784 	if GOOS == "windows" && _m_.libcallsp != 0 {
    785 		return false
    786 	}
    787 	return true
    788 }
    789