// Copyright 2014 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 (
	"internal/abi"
	"internal/goarch"
	"internal/runtime/atomic"
	"internal/runtime/sys"
	"internal/stringslite"
	"unsafe"
)

// throwType indicates the current type of ongoing throw, which affects the
// amount of detail printed to stderr. Higher values include more detail.
type throwType uint32

const (
	// throwTypeNone means that we are not throwing.
	throwTypeNone throwType = iota

	// throwTypeUser is a throw due to a problem with the application.
	//
	// These throws do not include runtime frames, system goroutines, or
	// frame metadata.
	throwTypeUser

	// throwTypeRuntime is a throw due to a problem with Go itself.
	//
	// These throws include as much information as possible to aid in
	// debugging the runtime, including runtime frames, system goroutines,
	// and frame metadata.
	throwTypeRuntime
)

// We have two different ways of doing defers. The older way involves creating a
// defer record at the time that a defer statement is executing and adding it to a
// defer chain. This chain is inspected by the deferreturn call at all function
// exits in order to run the appropriate defer calls. A cheaper way (which we call
// open-coded defers) is used for functions in which no defer statements occur in
// loops. In that case, we simply store the defer function/arg information into
// specific stack slots at the point of each defer statement, as well as setting a
// bit in a bitmask. At each function exit, we add inline code to directly make
// the appropriate defer calls based on the bitmask and fn/arg information stored
// on the stack. During panic/Goexit processing, the appropriate defer calls are
// made using extra funcdata info that indicates the exact stack slots that
// contain the bitmask and defer fn/args.

// Check to make sure we can really generate a panic. If the panic
// was generated from the runtime, or from inside malloc, then convert
// to a throw of msg.
// pc should be the program counter of the compiler-generated code that
// triggered this panic.
func panicCheck1(pc uintptr, msg string) {
	if goarch.IsWasm == 0 && stringslite.HasPrefix(funcname(findfunc(pc)), "runtime.") {
		// Note: wasm can't tail call, so we can't get the original caller's pc.
		throw(msg)
	}
	// TODO: is this redundant? How could we be in malloc
	// but not in the runtime? internal/runtime/*, maybe?
	gp := getg()
	if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
		throw(msg)
	}
}

// Same as above, but calling from the runtime is allowed.
//
// Using this function is necessary for any panic that may be
// generated by runtime.sigpanic, since those are always called by the
// runtime.
func panicCheck2(err string) {
	// panic allocates, so to avoid recursive malloc, turn panics
	// during malloc into throws.
	gp := getg()
	if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
		throw(err)
	}
}

// Many of the following panic entry-points turn into throws when they
// happen in various runtime contexts. These should never happen in
// the runtime, and if they do, they indicate a serious issue and
// should not be caught by user code.
//
// The panic{Index,Slice,divide,shift} functions are called by
// code generated by the compiler for out of bounds index expressions,
// out of bounds slice expressions, division by zero, and shift by negative.
// The panicdivide (again), panicoverflow, panicfloat, and panicmem
// functions are called by the signal handler when a signal occurs
// indicating the respective problem.
//
// Since panic{Index,Slice,shift} are never called directly, and
// since the runtime package should never have an out of bounds slice
// or array reference or negative shift, if we see those functions called from the
// runtime package we turn the panic into a throw. That will dump the
// entire runtime stack for easier debugging.
//
// The entry points called by the signal handler will be called from
// runtime.sigpanic, so we can't disallow calls from the runtime to
// these (they always look like they're called from the runtime).
// Hence, for these, we just check for clearly bad runtime conditions.
//
// The goPanic{Index,Slice} functions are only used by wasm. All the other architectures
// use panic{Bounds,Extend} in assembly, which then call to panicBounds{64,32,32X}.

// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
//
//go:yeswritebarrierrec
func goPanicIndex(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "index out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsIndex})
}

//go:yeswritebarrierrec
func goPanicIndexU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "index out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsIndex})
}

// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
//
//go:yeswritebarrierrec
func goPanicSliceAlen(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAlen})
}

//go:yeswritebarrierrec
func goPanicSliceAlenU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAlen})
}

//go:yeswritebarrierrec
func goPanicSliceAcap(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAcap})
}

//go:yeswritebarrierrec
func goPanicSliceAcapU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAcap})
}

// failures in the comparisons for s[x:y], 0 <= x <= y
//
//go:yeswritebarrierrec
func goPanicSliceB(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceB})
}

//go:yeswritebarrierrec
func goPanicSliceBU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceB})
}

// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
func goPanicSlice3Alen(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Alen})
}
func goPanicSlice3AlenU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Alen})
}
func goPanicSlice3Acap(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Acap})
}
func goPanicSlice3AcapU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Acap})
}

// failures in the comparisons for s[:x:y], 0 <= x <= y
func goPanicSlice3B(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3B})
}
func goPanicSlice3BU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3B})
}

// failures in the comparisons for s[x:y:], 0 <= x <= y
func goPanicSlice3C(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3C})
}
func goPanicSlice3CU(x uint, y int) {
	panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
	panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3C})
}

// failures in the conversion ([x]T)(s) or (*[x]T)(s), 0 <= x <= y, y == len(s)
func goPanicSliceConvert(x int, y int) {
	panicCheck1(sys.GetCallerPC(), "slice length too short to convert to array or pointer to array")
	panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsConvert})
}

// Implemented in assembly. Declared here to mark them as ABIInternal.
func panicBounds() // in asm_GOARCH.s files, called from generated code
func panicExtend() // in asm_GOARCH.s files, called from generated code (on 32-bit archs)

func panicBounds64(pc uintptr, regs *[16]int64) { // called from panicBounds on 64-bit archs
	f := findfunc(pc)
	v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)

	code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))

	if code == abi.BoundsIndex {
		panicCheck1(pc, "index out of range")
	} else {
		panicCheck1(pc, "slice bounds out of range")
	}

	var e boundsError
	e.code = code
	e.signed = signed
	if xIsReg {
		e.x = regs[xVal]
	} else {
		e.x = int64(xVal)
	}
	if yIsReg {
		e.y = int(regs[yVal])
	} else {
		e.y = yVal
	}
	panic(e)
}

func panicBounds32(pc uintptr, regs *[16]int32) { // called from panicBounds on 32-bit archs
	f := findfunc(pc)
	v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)

	code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))

	if code == abi.BoundsIndex {
		panicCheck1(pc, "index out of range")
	} else {
		panicCheck1(pc, "slice bounds out of range")
	}

	var e boundsError
	e.code = code
	e.signed = signed
	if xIsReg {
		if signed {
			e.x = int64(regs[xVal])
		} else {
			e.x = int64(uint32(regs[xVal]))
		}
	} else {
		e.x = int64(xVal)
	}
	if yIsReg {
		e.y = int(regs[yVal])
	} else {
		e.y = yVal
	}
	panic(e)
}

func panicBounds32X(pc uintptr, regs *[16]int32) { // called from panicExtend on 32-bit archs
	f := findfunc(pc)
	v := pcdatavalue(f, abi.PCDATA_PanicBounds, pc-1)

	code, signed, xIsReg, yIsReg, xVal, yVal := abi.BoundsDecode(int(v))

	if code == abi.BoundsIndex {
		panicCheck1(pc, "index out of range")
	} else {
		panicCheck1(pc, "slice bounds out of range")
	}

	var e boundsError
	e.code = code
	e.signed = signed
	if xIsReg {
		// Our 4-bit register numbers are actually 2 2-bit register numbers.
		lo := xVal & 3
		hi := xVal >> 2
		e.x = int64(regs[hi])<<32 + int64(uint32(regs[lo]))
	} else {
		e.x = int64(xVal)
	}
	if yIsReg {
		e.y = int(regs[yVal])
	} else {
		e.y = yVal
	}
	panic(e)
}

var shiftError = error(errorString("negative shift amount"))

//go:yeswritebarrierrec
func panicshift() {
	panicCheck1(sys.GetCallerPC(), "negative shift amount")
	panic(shiftError)
}

var divideError = error(errorString("integer divide by zero"))

//go:yeswritebarrierrec
func panicdivide() {
	panicCheck2("integer divide by zero")
	panic(divideError)
}

var overflowError = error(errorString("integer overflow"))

func panicoverflow() {
	panicCheck2("integer overflow")
	panic(overflowError)
}

var floatError = error(errorString("floating point error"))

func panicfloat() {
	panicCheck2("floating point error")
	panic(floatError)
}

var memoryError = error(errorString("invalid memory address or nil pointer dereference"))

func panicmem() {
	panicCheck2("invalid memory address or nil pointer dereference")
	panic(memoryError)
}

func panicmemAddr(addr uintptr) {
	panicCheck2("invalid memory address or nil pointer dereference")
	panic(errorAddressString{msg: "invalid memory address or nil pointer dereference", addr: addr})
}

var simdImmError = error(errorString("out-of-range immediate for simd intrinsic"))

func panicSimdImm() {
	panicCheck2("simd immediate error")
	panic(simdImmError)
}

// Create a new deferred function fn, which has no arguments and results.
// The compiler turns a defer statement into a call to this.
func deferproc(fn func()) {
	gp := getg()
	if gp.m.curg != gp {
		// go code on the system stack can't defer
		throw("defer on system stack")
	}

	d := newdefer()
	d.link = gp._defer
	gp._defer = d
	d.fn = fn
	d.pc = sys.GetCallerPC()
	// We must not be preempted between calling GetCallerSP and
	// storing it to d.sp because GetCallerSP's result is a
	// uintptr stack pointer.
	d.sp = sys.GetCallerSP()
}

var rangeDoneError = error(errorString("range function continued iteration after function for loop body returned false"))
var rangePanicError = error(errorString("range function continued iteration after loop body panic"))
var rangeExhaustedError = error(errorString("range function continued iteration after whole loop exit"))
var rangeMissingPanicError = error(errorString("range function recovered a loop body panic and did not resume panicking"))

//go:noinline
func panicrangestate(state int) {
	switch abi.RF_State(state) {
	case abi.RF_DONE:
		panic(rangeDoneError)
	case abi.RF_PANIC:
		panic(rangePanicError)
	case abi.RF_EXHAUSTED:
		panic(rangeExhaustedError)
	case abi.RF_MISSING_PANIC:
		panic(rangeMissingPanicError)
	}
	throw("unexpected state passed to panicrangestate")
}

// deferrangefunc is called by functions that are about to
// execute a range-over-function loop in which the loop body
// may execute a defer statement. That defer needs to add to
// the chain for the current function, not the func literal synthesized
// to represent the loop body. To do that, the original function
// calls deferrangefunc to obtain an opaque token representing
// the current frame, and then the loop body uses deferprocat
// instead of deferproc to add to that frame's defer lists.
//
// The token is an 'any' with underlying type *atomic.Pointer[_defer].
// It is the atomically-updated head of a linked list of _defer structs
// representing deferred calls. At the same time, we create a _defer
// struct on the main g._defer list with d.head set to this head pointer.
//
// The g._defer list is now a linked list of deferred calls,
// but an atomic list hanging off:
//
//		g._defer => d4 -> d3 -> drangefunc -> d2 -> d1 -> nil
//	                             | .head
//	                             |
//	                             +--> dY -> dX -> nil
//
// with each -> indicating a d.link pointer, and where drangefunc
// has the d.rangefunc = true bit set.
// Note that the function being ranged over may have added
// its own defers (d4 and d3), so drangefunc need not be at the
// top of the list when deferprocat is used. This is why we pass
// the atomic head explicitly.
//
// To keep misbehaving programs from crashing the runtime,
// deferprocat pushes new defers onto the .head list atomically.
// The fact that it is a separate list from the main goroutine
// defer list means that the main goroutine's defers can still
// be handled non-atomically.
//
// In the diagram, dY and dX are meant to be processed when
// drangefunc would be processed, which is to say the defer order
// should be d4, d3, dY, dX, d2, d1. To make that happen,
// when defer processing reaches a d with rangefunc=true,
// it calls deferconvert to atomically take the extras
// away from d.head and then adds them to the main list.
//
// That is, deferconvert changes this list:
//
//		g._defer => drangefunc -> d2 -> d1 -> nil
//	                 | .head
//	                 |
//	                 +--> dY -> dX -> nil
//
// into this list:
//
//	g._defer => dY -> dX -> d2 -> d1 -> nil
//
// It also poisons *drangefunc.head so that any future
// deferprocat using that head will throw.
// (The atomic head is ordinary garbage collected memory so that
// it's not a problem if user code holds onto it beyond
// the lifetime of drangefunc.)
//
// TODO: We could arrange for the compiler to call into the
// runtime after the loop finishes normally, to do an eager
// deferconvert, which would catch calling the loop body
// and having it defer after the loop is done. If we have a
// more general catch of loop body misuse, though, this
// might not be worth worrying about in addition.
//
// See also ../cmd/compile/internal/rangefunc/rewrite.go.
func deferrangefunc() any {
	gp := getg()
	if gp.m.curg != gp {
		// go code on the system stack can't defer
		throw("defer on system stack")
	}

	d := newdefer()
	d.link = gp._defer
	gp._defer = d
	d.pc = sys.GetCallerPC()
	// We must not be preempted between calling GetCallerSP and
	// storing it to d.sp because GetCallerSP's result is a
	// uintptr stack pointer.
	d.sp = sys.GetCallerSP()

	d.rangefunc = true
	d.head = new(atomic.Pointer[_defer])

	return d.head
}

// badDefer returns a fixed bad defer pointer for poisoning an atomic defer list head.
func badDefer() *_defer {
	return (*_defer)(unsafe.Pointer(uintptr(1)))
}

// deferprocat is like deferproc but adds to the atomic list represented by frame.
// See the doc comment for deferrangefunc for details.
func deferprocat(fn func(), frame any) {
	head := frame.(*atomic.Pointer[_defer])
	if raceenabled {
		racewritepc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferprocat))
	}
	d1 := newdefer()
	d1.fn = fn
	for {
		d1.link = head.Load()
		if d1.link == badDefer() {
			throw("defer after range func returned")
		}
		if head.CompareAndSwap(d1.link, d1) {
			break
		}
	}
}

// deferconvert converts the rangefunc defer list of d0 into an ordinary list
// following d0.
// See the doc comment for deferrangefunc for details.
func deferconvert(d0 *_defer) {
	head := d0.head
	if raceenabled {
		racereadpc(unsafe.Pointer(head), sys.GetCallerPC(), abi.FuncPCABIInternal(deferconvert))
	}
	tail := d0.link
	d0.rangefunc = false

	var d *_defer
	for {
		d = head.Load()
		if head.CompareAndSwap(d, badDefer()) {
			break
		}
	}
	if d == nil {
		return
	}
	for d1 := d; ; d1 = d1.link {
		d1.sp = d0.sp
		d1.pc = d0.pc
		if d1.link == nil {
			d1.link = tail
			break
		}
	}
	d0.link = d
	return
}

// deferprocStack queues a new deferred function with a defer record on the stack.
// The defer record must have its fn field initialized.
// All other fields can contain junk.
// Nosplit because of the uninitialized pointer fields on the stack.
//
//go:nosplit
func deferprocStack(d *_defer) {
	gp := getg()
	if gp.m.curg != gp {
		// go code on the system stack can't defer
		throw("defer on system stack")
	}

	// fn is already set.
	// The other fields are junk on entry to deferprocStack and
	// are initialized here.
	d.heap = false
	d.rangefunc = false
	d.sp = sys.GetCallerSP()
	d.pc = sys.GetCallerPC()
	// The lines below implement:
	//   d.link = gp._defer
	//   d.head = nil
	//   gp._defer = d
	// But without write barriers. The first two are writes to
	// the stack so they don't need a write barrier, and furthermore
	// are to uninitialized memory, so they must not use a write barrier.
	// The third write does not require a write barrier because we
	// explicitly mark all the defer structures, so we don't need to
	// keep track of pointers to them with a write barrier.
	*(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
	*(*uintptr)(unsafe.Pointer(&d.head)) = 0
	*(*uintptr)(unsafe.Pointer(&gp._defer)) = uintptr(unsafe.Pointer(d))
}

// Each P holds a pool for defers.

// Allocate a Defer, usually using per-P pool.
// Each defer must be released with freedefer.  The defer is not
// added to any defer chain yet.
func newdefer() *_defer {
	var d *_defer
	mp := acquirem()
	pp := mp.p.ptr()
	if len(pp.deferpool) == 0 && sched.deferpool != nil {
		lock(&sched.deferlock)
		for len(pp.deferpool) < cap(pp.deferpool)/2 && sched.deferpool != nil {
			d := sched.deferpool
			sched.deferpool = d.link
			d.link = nil
			pp.deferpool = append(pp.deferpool, d)
		}
		unlock(&sched.deferlock)
	}
	if n := len(pp.deferpool); n > 0 {
		d = pp.deferpool[n-1]
		pp.deferpool[n-1] = nil
		pp.deferpool = pp.deferpool[:n-1]
	}
	releasem(mp)
	mp, pp = nil, nil

	if d == nil {
		// Allocate new defer.
		d = new(_defer)
	}
	d.heap = true
	return d
}

// popDefer pops the head of gp's defer list and frees it.
func popDefer(gp *g) {
	d := gp._defer
	d.fn = nil // Can in theory point to the stack
	// We must not copy the stack between the updating gp._defer and setting
	// d.link to nil. Between these two steps, d is not on any defer list, so
	// stack copying won't adjust stack pointers in it (namely, d.link). Hence,
	// if we were to copy the stack, d could then contain a stale pointer.
	gp._defer = d.link
	d.link = nil
	// After this point we can copy the stack.

	if !d.heap {
		return
	}

	mp := acquirem()
	pp := mp.p.ptr()
	if len(pp.deferpool) == cap(pp.deferpool) {
		// Transfer half of local cache to the central cache.
		var first, last *_defer
		for len(pp.deferpool) > cap(pp.deferpool)/2 {
			n := len(pp.deferpool)
			d := pp.deferpool[n-1]
			pp.deferpool[n-1] = nil
			pp.deferpool = pp.deferpool[:n-1]
			if first == nil {
				first = d
			} else {
				last.link = d
			}
			last = d
		}
		lock(&sched.deferlock)
		last.link = sched.deferpool
		sched.deferpool = first
		unlock(&sched.deferlock)
	}

	*d = _defer{}

	pp.deferpool = append(pp.deferpool, d)

	releasem(mp)
	mp, pp = nil, nil
}

// deferreturn runs deferred functions for the caller's frame.
// The compiler inserts a call to this at the end of any
// function which calls defer.
func deferreturn() {
	var p _panic
	p.deferreturn = true

	p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
	for {
		fn, ok := p.nextDefer()
		if !ok {
			break
		}
		fn()
	}
}

// Goexit terminates the goroutine that calls it. No other goroutine is affected.
// Goexit runs all deferred calls before terminating the goroutine. Because Goexit
// is not a panic, any recover calls in those deferred functions will return nil.
//
// Calling Goexit from the main goroutine terminates that goroutine
// without func main returning. Since func main has not returned,
// the program continues execution of other goroutines.
// If all other goroutines exit, the program crashes.
//
// It crashes if called from a thread not created by the Go runtime.
func Goexit() {
	// 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.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
	for {
		fn, ok := p.nextDefer()
		if !ok {
			break
		}
		fn()
	}

	goexit1()
}

// Call all Error and String methods before freezing the world.
// Used when crashing with panicking.
func preprintpanics(p *_panic) {
	defer func() {
		text := "panic while printing panic value"
		switch r := recover().(type) {
		case nil:
			// nothing to do
		case string:
			throw(text + ": " + r)
		default:
			throw(text + ": type " + toRType(efaceOf(&r)._type).string())
		}
	}()
	for p != nil {
		if p.link != nil && *efaceOf(&p.link.arg) == *efaceOf(&p.arg) {
			// This panic contains the same value as the next one in the chain.
			// Mark it as repanicked. We will skip printing it twice in a row.
			p.link.repanicked = true
			p = p.link
			continue
		}
		switch v := p.arg.(type) {
		case error:
			p.arg = v.Error()
		case stringer:
			p.arg = v.String()
		}
		p = p.link
	}
}

// Print all currently active panics. Used when crashing.
// Should only be called after preprintpanics.
func printpanics(p *_panic) {
	if p.link != nil {
		printpanics(p.link)
		if p.link.repanicked {
			return
		}
		if !p.link.goexit {
			print("\t")
		}
	}
	if p.goexit {
		return
	}
	print("panic: ")
	printpanicval(p.arg)
	if p.recovered && p.repanicked {
		print(" [recovered, repanicked]")
	} else if p.recovered {
		print(" [recovered]")
	}
	print("\n")
}

// readvarintUnsafe reads the uint32 in varint format starting at fd, and returns the
// uint32 and a pointer to the byte following the varint.
//
// The implementation is the same with runtime.readvarint, except that this function
// uses unsafe.Pointer for speed.
func readvarintUnsafe(fd unsafe.Pointer) (uint32, unsafe.Pointer) {
	var r uint32
	var shift int
	for {
		b := *(*uint8)(fd)
		fd = add(fd, unsafe.Sizeof(b))
		if b < 128 {
			return r + uint32(b)<<shift, fd
		}
		r += uint32(b&0x7F) << (shift & 31)
		shift += 7
		if shift > 28 {
			panic("Bad varint")
		}
	}
}

// A PanicNilError happens when code calls panic(nil).
//
// Before Go 1.21, programs that called panic(nil) observed recover returning nil.
// Starting in Go 1.21, programs that call panic(nil) observe recover returning a *PanicNilError.
// Programs can change back to the old behavior by setting GODEBUG=panicnil=1.
type PanicNilError struct {
	// This field makes PanicNilError structurally different from
	// any other struct in this package, and the _ makes it different
	// from any struct in other packages too.
	// This avoids any accidental conversions being possible
	// between this struct and some other struct sharing the same fields,
	// like happened in go.dev/issue/56603.
	_ [0]*PanicNilError
}

func (*PanicNilError) Error() string { return "panic called with nil argument" }
func (*PanicNilError) RuntimeError() {}

var panicnil = &godebugInc{name: "panicnil"}

// The implementation of the predeclared function panic.
// The compiler emits calls to this function.
//
// gopanic should be an internal detail,
// but historically, widely used packages access it using linkname.
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname gopanic
func gopanic(e any) {
	if e == nil {
		if debug.panicnil.Load() != 1 {
			e = new(PanicNilError)
		} else {
			panicnil.IncNonDefault()
		}
	}

	gp := getg()
	if gp.m.curg != gp {
		print("panic: ")
		printpanicval(e)
		print("\n")
		throw("panic on system stack")
	}

	if gp.m.mallocing != 0 {
		print("panic: ")
		printpanicval(e)
		print("\n")
		throw("panic during malloc")
	}
	if gp.m.preemptoff != "" {
		print("panic: ")
		printpanicval(e)
		print("\n")
		print("preempt off reason: ")
		print(gp.m.preemptoff)
		print("\n")
		throw("panic during preemptoff")
	}
	if gp.m.locks != 0 {
		print("panic: ")
		printpanicval(e)
		print("\n")
		throw("panic holding locks")
	}

	var p _panic
	p.arg = e

	runningPanicDefers.Add(1)

	p.start(sys.GetCallerPC(), unsafe.Pointer(sys.GetCallerSP()))
	for {
		fn, ok := p.nextDefer()
		if !ok {
			break
		}
		fn()
	}

	// If we're tracing, flush the current generation to make the trace more
	// readable.
	//
	// TODO(aktau): Handle a panic from within traceAdvance more gracefully.
	// Currently it would hang. Not handled now because it is very unlikely, and
	// already unrecoverable.
	if traceEnabled() {
		traceAdvance(false)
	}

	// ran out of deferred calls - old-school panic now
	// Because it is unsafe to call arbitrary user code after freezing
	// the world, we call preprintpanics to invoke all necessary Error
	// and String methods to prepare the panic strings before startpanic.
	preprintpanics(&p)

	fatalpanic(&p)   // should not return
	*(*int)(nil) = 0 // not reached
}

// start initializes a panic to start unwinding the stack.
//
// If p.goexit is true, then start may return multiple times.
func (p *_panic) start(pc uintptr, sp unsafe.Pointer) {
	gp := getg()

	// Record the caller's PC and SP, so recovery can identify panics
	// that have been recovered. Also, so that if p is from Goexit, we
	// can restart its defer processing loop if a recovered panic tries
	// to jump past it.
	p.startPC = sys.GetCallerPC()
	p.startSP = unsafe.Pointer(sys.GetCallerSP())

	if p.deferreturn {
		p.sp = sp

		if s := (*savedOpenDeferState)(gp.param); s != nil {
			// recovery saved some state for us, so that we can resume
			// calling open-coded defers without unwinding the stack.

			gp.param = nil

			p.retpc = s.retpc
			p.deferBitsPtr = (*byte)(add(sp, s.deferBitsOffset))
			p.slotsPtr = add(sp, s.slotsOffset)
		}

		return
	}

	p.link = gp._panic
	gp._panic = (*_panic)(noescape(unsafe.Pointer(p)))

	// Initialize state machine, and find the first frame with a defer.
	//
	// Note: We could use startPC and startSP here, but callers will
	// never have defer statements themselves. By starting at their
	// caller instead, we avoid needing to unwind through an extra
	// frame. It also somewhat simplifies the terminating condition for
	// deferreturn.
	p.pc, p.sp = pc, sp
	p.nextFrame()
}

// nextDefer returns the next deferred function to invoke, if any.
//
// Note: The "ok bool" result is necessary to correctly handle when
// the deferred function itself was nil (e.g., "defer (func())(nil)").
func (p *_panic) nextDefer() (func(), bool) {
	gp := getg()

	if !p.deferreturn {
		if gp._panic != p {
			throw("bad panic stack")
		}

		if p.recovered {
			mcall(recovery) // does not return
			throw("recovery failed")
		}
	}

	for {
		for p.deferBitsPtr != nil {
			bits := *p.deferBitsPtr

			// Check whether any open-coded defers are still pending.
			//
			// Note: We need to check this upfront (rather than after
			// clearing the top bit) because it's possible that Goexit
			// invokes a deferred call, and there were still more pending
			// open-coded defers in the frame; but then the deferred call
			// panic and invoked the remaining defers in the frame, before
			// recovering and restarting the Goexit loop.
			if bits == 0 {
				p.deferBitsPtr = nil
				break
			}

			// Find index of top bit set.
			i := 7 - uintptr(sys.LeadingZeros8(bits))

			// Clear bit and store it back.
			bits &^= 1 << i
			*p.deferBitsPtr = bits

			return *(*func())(add(p.slotsPtr, i*goarch.PtrSize)), true
		}

	Recheck:
		if d := gp._defer; d != nil && d.sp == uintptr(p.sp) {
			if d.rangefunc {
				deferconvert(d)
				popDefer(gp)
				goto Recheck
			}

			fn := d.fn

			p.retpc = d.pc

			// Unlink and free.
			popDefer(gp)

			return fn, true
		}

		if !p.nextFrame() {
			return nil, false
		}
	}
}

// nextFrame finds the next frame that contains deferred calls, if any.
func (p *_panic) nextFrame() (ok bool) {
	if p.pc == 0 {
		return false
	}

	gp := getg()
	systemstack(func() {
		var limit uintptr
		if d := gp._defer; d != nil {
			limit = d.sp
		}

		var u unwinder
		u.initAt(p.pc, uintptr(p.sp), 0, gp, 0)
		for {
			if !u.valid() {
				p.pc = 0
				return // ok == false
			}

			// TODO(mdempsky): If we populate u.frame.fn.deferreturn for
			// every frame containing a defer (not just open-coded defers),
			// then we can simply loop until we find the next frame where
			// it's non-zero.

			if u.frame.sp == limit {
				break // found a frame with linked defers
			}

			if p.initOpenCodedDefers(u.frame.fn, unsafe.Pointer(u.frame.varp)) {
				break // found a frame with open-coded defers
			}

			if p.link != nil && uintptr(u.frame.sp) == uintptr(p.link.startSP) && uintptr(p.link.sp) > u.frame.sp {
				// Skip ahead to where the next panic up the stack was last looking
				// for defers. See issue 77062.
				//
				// The startSP condition is to check when we have walked up the stack
				// to where the next panic up the stack started. If so, the processing
				// of that panic has run all the defers up to its current scanning
				// position.
				//
				// The final condition is just to make sure that the line below
				// is actually helpful.
				u.initAt(p.link.pc, uintptr(p.link.sp), 0, gp, 0)
				continue
			}

			u.next()
		}

		p.pc = u.frame.pc
		p.sp = unsafe.Pointer(u.frame.sp)
		p.fp = unsafe.Pointer(u.frame.fp)

		ok = true
	})

	return
}

func (p *_panic) initOpenCodedDefers(fn funcInfo, varp unsafe.Pointer) bool {
	fd := funcdata(fn, abi.FUNCDATA_OpenCodedDeferInfo)
	if fd == nil {
		return false
	}

	if fn.deferreturn == 0 {
		throw("missing deferreturn")
	}

	deferBitsOffset, fd := readvarintUnsafe(fd)
	deferBitsPtr := (*uint8)(add(varp, -uintptr(deferBitsOffset)))
	if *deferBitsPtr == 0 {
		return false // has open-coded defers, but none pending
	}

	slotsOffset, fd := readvarintUnsafe(fd)

	p.retpc = fn.entry() + uintptr(fn.deferreturn)
	p.deferBitsPtr = deferBitsPtr
	p.slotsPtr = add(varp, -uintptr(slotsOffset))

	return true
}

// The implementation of the predeclared function recover.
func gorecover() any {
	gp := getg()
	p := gp._panic
	if p == nil || p.goexit || p.recovered {
		return nil
	}

	// Check to see if the function that called recover() was
	// deferred directly from the panicking function.
	// For code like:
	//     func foo() {
	//         defer bar()
	//         panic("panic")
	//     }
	//     func bar() {
	//         recover()
	//     }
	// Normally the stack would look like this:
	//     foo
	//     runtime.gopanic
	//     bar
	//     runtime.gorecover
	//
	// However, if the function we deferred requires a wrapper
	// of some sort, we need to ignore the wrapper. In that case,
	// the stack looks like:
	//     foo
	//     runtime.gopanic
	//     wrapper
	//     bar
	//     runtime.gorecover
	// And we should also successfully recover.
	//
	// Finally, in the weird case "defer recover()", the stack looks like:
	//     foo
	//     runtime.gopanic
	//     wrapper
	//     runtime.gorecover
	// And we should not recover in that case.
	//
	// So our criteria is, there must be exactly one non-wrapper
	// frame between gopanic and gorecover.
	//
	// We don't recover this:
	//     defer func() { func() { recover() }() }()
	// because there are 2 non-wrapper frames.
	//
	// We don't recover this:
	//     defer recover()
	// because there are 0 non-wrapper frames.
	canRecover := false
	systemstack(func() {
		var u unwinder
		u.init(gp, 0)
		u.next() // skip systemstack_switch
		u.next() // skip gorecover
		nonWrapperFrames := 0
	loop:
		for ; u.valid(); u.next() {
			for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
				sf := iu.srcFunc(f)
				switch sf.funcID {
				case abi.FuncIDWrapper:
					continue
				case abi.FuncID_gopanic:
					if u.frame.sp == uintptr(p.startSP) && nonWrapperFrames > 0 {
						canRecover = true
					}
					break loop
				default:
					nonWrapperFrames++
					if nonWrapperFrames > 1 {
						break loop
					}
				}
			}
		}
	})
	if !canRecover {
		return nil
	}
	p.recovered = true
	return p.arg
}

//go:linkname sync_throw sync.throw
func sync_throw(s string) {
	throw(s)
}

//go:linkname sync_fatal sync.fatal
func sync_fatal(s string) {
	fatal(s)
}

//go:linkname rand_fatal crypto/rand.fatal
func rand_fatal(s string) {
	fatal(s)
}

//go:linkname sysrand_fatal crypto/internal/sysrand.fatal
func sysrand_fatal(s string) {
	fatal(s)
}

//go:linkname fips_fatal crypto/internal/fips140.fatal
func fips_fatal(s string) {
	fatal(s)
}

//go:linkname maps_fatal internal/runtime/maps.fatal
func maps_fatal(s string) {
	fatal(s)
}

//go:linkname internal_sync_throw internal/sync.throw
func internal_sync_throw(s string) {
	throw(s)
}

//go:linkname internal_sync_fatal internal/sync.fatal
func internal_sync_fatal(s string) {
	fatal(s)
}

//go:linkname cgroup_throw internal/runtime/cgroup.throw
func cgroup_throw(s string) {
	throw(s)
}

// throw triggers a fatal error that dumps a stack trace and exits.
//
// throw should be used for runtime-internal fatal errors where Go itself,
// rather than user code, may be at fault for the failure.
//
// throw should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
//   - github.com/bytedance/sonic
//   - github.com/cockroachdb/pebble
//   - github.com/dgraph-io/ristretto
//   - github.com/outcaste-io/ristretto
//   - github.com/pingcap/br
//   - gvisor.dev/gvisor
//   - github.com/sagernet/gvisor
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname throw
//go:nosplit
func throw(s string) {
	// Everything throw does should be recursively nosplit so it
	// can be called even when it's unsafe to grow the stack.
	systemstack(func() {
		print("fatal error: ")
		printindented(s) // logically printpanicval(s), but avoids convTstring write barrier
		print("\n")
	})

	fatalthrow(throwTypeRuntime)
}

// fatal triggers a fatal error that dumps a stack trace and exits.
//
// fatal is equivalent to throw, but is used when user code is expected to be
// at fault for the failure, such as racing map writes.
//
// fatal does not include runtime frames, system goroutines, or frame metadata
// (fp, sp, pc) in the stack trace unless GOTRACEBACK=system or higher.
//
//go:nosplit
func fatal(s string) {
	p := getg()._panic
	// Everything fatal does should be recursively nosplit so it
	// can be called even when it's unsafe to grow the stack.
	printlock() // Prevent multiple interleaved fatal reports. See issue 69447.
	systemstack(func() {
		printPreFatalDeferPanic(p)
		print("fatal error: ")
		printindented(s) // logically printpanicval(s), but avoids convTstring write barrier
		print("\n")
	})

	fatalthrow(throwTypeUser)
	printunlock()
}

// printPreFatalDeferPanic prints the panic
// when fatal occurs in panics while running defer.
func printPreFatalDeferPanic(p *_panic) {
	// Don`t call preprintpanics, because
	// don't want to call String/Error on the panicked values.
	// When we fatal we really want to just print and exit,
	// no more executing user Go code.
	for x := p; x != nil; x = x.link {
		if x.link != nil && *efaceOf(&x.link.arg) == *efaceOf(&x.arg) {
			// This panic contains the same value as the next one in the chain.
			// Mark it as repanicked. We will skip printing it twice in a row.
			x.link.repanicked = true
		}
	}
	if p != nil {
		printpanics(p)
		// make fatal have the same indentation as non-first panics.
		print("\t")
	}
}

// runningPanicDefers is non-zero while running deferred functions for panic.
// This is used to try hard to get a panic stack trace out when exiting.
var runningPanicDefers atomic.Uint32

// panicking is non-zero when crashing the program for an unrecovered panic.
var panicking atomic.Uint32

// paniclk is held while printing the panic information and stack trace,
// so that two concurrent panics don't overlap their output.
var paniclk mutex

// Unwind the stack after a deferred function calls recover
// after a panic. Then arrange to continue running as though
// the caller of the deferred function returned normally.
//
// However, if unwinding the stack would skip over a Goexit call, we
// return into the Goexit loop instead, so it can continue processing
// defers instead.
func recovery(gp *g) {
	p := gp._panic
	pc, sp, fp := p.retpc, uintptr(p.sp), uintptr(p.fp)
	p0, saveOpenDeferState := p, p.deferBitsPtr != nil && *p.deferBitsPtr != 0

	// The linker records the f-relative address of a call to deferreturn in f's funcInfo.
	// Assuming a "normal" call to recover() inside one of f's deferred functions
	// invoked for a panic, that is the desired PC for exiting f.
	f := findfunc(pc)
	if f.deferreturn == 0 {
		throw("no deferreturn")
	}
	gotoPc := f.entry() + uintptr(f.deferreturn)

	// Unwind the panic stack.
	for ; p != nil && uintptr(p.startSP) < sp; p = p.link {
		// Don't allow jumping past a pending Goexit.
		// Instead, have its _panic.start() call return again.
		//
		// TODO(mdempsky): In this case, Goexit will resume walking the
		// stack where it left off, which means it will need to rewalk
		// frames that we've already processed.
		//
		// There's a similar issue with nested panics, when the inner
		// panic supersedes the outer panic. Again, we end up needing to
		// walk the same stack frames.
		//
		// These are probably pretty rare occurrences in practice, and
		// they don't seem any worse than the existing logic. But if we
		// move the unwinding state into _panic, we could detect when we
		// run into where the last panic started, and then just pick up
		// where it left off instead.
		//
		// With how subtle defer handling is, this might not actually be
		// worthwhile though.
		if p.goexit {
			gotoPc, sp = p.startPC, uintptr(p.startSP)
			saveOpenDeferState = false // goexit is unwinding the stack anyway
			break
		}

		runningPanicDefers.Add(-1)
	}
	gp._panic = p

	if p == nil { // must be done with signal
		gp.sig = 0
	}

	if gp.param != nil {
		throw("unexpected gp.param")
	}
	if saveOpenDeferState {
		// If we're returning to deferreturn and there are more open-coded
		// defers for it to call, save enough state for it to be able to
		// pick up where p0 left off.
		gp.param = unsafe.Pointer(&savedOpenDeferState{
			retpc: p0.retpc,

			// We need to save deferBitsPtr and slotsPtr too, but those are
			// stack pointers. To avoid issues around heap objects pointing
			// to the stack, save them as offsets from SP.
			deferBitsOffset: uintptr(unsafe.Pointer(p0.deferBitsPtr)) - uintptr(p0.sp),
			slotsOffset:     uintptr(p0.slotsPtr) - uintptr(p0.sp),
		})
	}

	// TODO(mdempsky): Currently, we rely on frames containing "defer"
	// to end with "CALL deferreturn; RET". This allows deferreturn to
	// finish running any pending defers in the frame.
	//
	// But we should be able to tell whether there are still pending
	// defers here. If there aren't, we can just jump directly to the
	// "RET" instruction. And if there are, we don't need an actual
	// "CALL deferreturn" instruction; we can simulate it with something
	// like:
	//
	//	if usesLR {
	//		lr = pc
	//	} else {
	//		sp -= sizeof(pc)
	//		*(*uintptr)(sp) = pc
	//	}
	//	pc = funcPC(deferreturn)
	//
	// So that we effectively tail call into deferreturn, such that it
	// then returns to the simple "RET" epilogue. That would save the
	// overhead of the "deferreturn" call when there aren't actually any
	// pending defers left, and shrink the TEXT size of compiled
	// binaries. (Admittedly, both of these are modest savings.)

	// Ensure we're recovering within the appropriate stack.
	if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
		print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
		throw("bad recovery")
	}

	// branch directly to the deferreturn
	gp.sched.sp = sp
	gp.sched.pc = gotoPc
	gp.sched.lr = 0
	// Restore the bp on platforms that support frame pointers.
	// N.B. It's fine to not set anything for platforms that don't
	// support frame pointers, since nothing consumes them.
	switch {
	case goarch.IsAmd64 != 0:
		// on x86, fp actually points one word higher than the top of
		// the frame since the return address is saved on the stack by
		// the caller
		gp.sched.bp = fp - 2*goarch.PtrSize
	case goarch.IsArm64 != 0:
		// on arm64, the architectural bp points one word higher
		// than the sp. fp is totally useless to us here, because it
		// only gets us to the caller's fp.
		gp.sched.bp = sp - goarch.PtrSize
	}
	gogo(&gp.sched)
}

// fatalthrow implements an unrecoverable runtime throw. It freezes the
// system, prints stack traces starting from its caller, and terminates the
// process.
//
//go:nosplit
func fatalthrow(t throwType) {
	pc := sys.GetCallerPC()
	sp := sys.GetCallerSP()
	gp := getg()

	if gp.m.throwing == throwTypeNone {
		gp.m.throwing = t
	}

	// Switch to the system stack to avoid any stack growth, which may make
	// things worse if the runtime is in a bad state.
	systemstack(func() {
		if isSecureMode() {
			exit(2)
		}

		startpanic_m()

		if dopanic_m(gp, pc, sp, nil) {
			// crash uses a decent amount of nosplit stack and we're already
			// low on stack in throw, so crash on the system stack (unlike
			// fatalpanic).
			crash()
		}

		exit(2)
	})

	*(*int)(nil) = 0 // not reached
}

// fatalpanic implements an unrecoverable panic. It is like fatalthrow, except
// that if msgs != nil, fatalpanic also prints panic messages and decrements
// runningPanicDefers once main is blocked from exiting.
//
//go:nosplit
func fatalpanic(msgs *_panic) {
	pc := sys.GetCallerPC()
	sp := sys.GetCallerSP()
	gp := getg()
	var docrash bool
	// Switch to the system stack to avoid any stack growth, which
	// may make things worse if the runtime is in a bad state.
	systemstack(func() {
		if startpanic_m() && msgs != nil {
			// There were panic messages and startpanic_m
			// says it's okay to try to print them.

			// startpanic_m set panicking, which will
			// block main from exiting, so now OK to
			// decrement runningPanicDefers.
			runningPanicDefers.Add(-1)

			printpanics(msgs)
		}

		// If this panic is the result of a synctest bubble deadlock,
		// print stacks for the goroutines in the bubble.
		var bubble *synctestBubble
		if de, ok := msgs.arg.(synctestDeadlockError); ok {
			bubble = de.bubble
		}

		docrash = dopanic_m(gp, pc, sp, bubble)
	})

	if docrash {
		// By crashing outside the above systemstack call, debuggers
		// will not be confused when generating a backtrace.
		// Function crash is marked nosplit to avoid stack growth.
		crash()
	}

	systemstack(func() {
		exit(2)
	})

	*(*int)(nil) = 0 // not reached
}

// startpanic_m prepares for an unrecoverable panic.
//
// It returns true if panic messages should be printed, or false if
// the runtime is in bad shape and should just print stacks.
//
// It must not have write barriers even though the write barrier
// explicitly ignores writes once dying > 0. Write barriers still
// assume that g.m.p != nil, and this function may not have P
// in some contexts (e.g. a panic in a signal handler for a signal
// sent to an M with no P).
//
//go:nowritebarrierrec
func startpanic_m() bool {
	gp := getg()
	if mheap_.cachealloc.size == 0 { // very early
		print("runtime: panic before malloc heap initialized\n")
	}
	// Disallow malloc during an unrecoverable panic. A panic
	// could happen in a signal handler, or in a throw, or inside
	// malloc itself. We want to catch if an allocation ever does
	// happen (even if we're not in one of these situations).
	gp.m.mallocing++

	// If we're dying because of a bad lock count, set it to a
	// good lock count so we don't recursively panic below.
	if gp.m.locks < 0 {
		gp.m.locks = 1
	}

	switch gp.m.dying {
	case 0:
		// Setting dying >0 has the side-effect of disabling this G's writebuf.
		gp.m.dying = 1
		panicking.Add(1)
		lock(&paniclk)
		if debug.schedtrace > 0 || debug.scheddetail > 0 {
			schedtrace(true)
		}
		freezetheworld()
		return true
	case 1:
		// Something failed while panicking.
		// Just print a stack trace and exit.
		gp.m.dying = 2
		print("panic during panic\n")
		return false
	case 2:
		// This is a genuine bug in the runtime, we couldn't even
		// print the stack trace successfully.
		gp.m.dying = 3
		print("stack trace unavailable\n")
		exit(4)
		fallthrough
	default:
		// Can't even print! Just exit.
		exit(5)
		return false // Need to return something.
	}
}

var didothers bool
var deadlock mutex

// gp is the crashing g running on this M, but may be a user G, while getg() is
// always g0.
// If bubble is non-nil, print the stacks for goroutines in this group as well.
func dopanic_m(gp *g, pc, sp uintptr, bubble *synctestBubble) bool {
	if gp.sig != 0 {
		signame := signame(gp.sig)
		if signame != "" {
			print("[signal ", signame)
		} else {
			print("[signal ", hex(gp.sig))
		}
		print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
	}

	level, all, docrash := gotraceback()
	if level > 0 {
		if gp != gp.m.curg {
			all = true
		}
		if gp != gp.m.g0 {
			print("\n")
			goroutineheader(gp)
			traceback(pc, sp, 0, gp)
		} else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
			print("\nruntime stack:\n")
			traceback(pc, sp, 0, gp)
		}
		if !didothers {
			if all {
				didothers = true
				tracebackothers(gp)
			} else if bubble != nil {
				// This panic is caused by a synctest bubble deadlock.
				// Print stacks for goroutines in the deadlocked bubble.
				tracebacksomeothers(gp, func(other *g) bool {
					return bubble == other.bubble
				})
			}
		}

	}
	unlock(&paniclk)

	if panicking.Add(-1) != 0 {
		// Some other m is panicking too.
		// Let it print what it needs to print.
		// Wait forever without chewing up cpu.
		// It will exit when it's done.
		lock(&deadlock)
		lock(&deadlock)
	}

	printDebugLog()

	return docrash
}

// canpanic returns false if a signal should throw instead of
// panicking.
//
//go:nosplit
func canpanic() bool {
	gp := getg()
	mp := acquirem()

	// Is it okay for gp to panic instead of crashing the program?
	// Yes, as long as it is running Go code, not runtime code,
	// and not stuck in a system call.
	if gp != mp.curg {
		releasem(mp)
		return false
	}
	// N.B. mp.locks != 1 instead of 0 to account for acquirem.
	if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
		releasem(mp)
		return false
	}
	status := readgstatus(gp)
	if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
		releasem(mp)
		return false
	}
	if GOOS == "windows" && mp.libcallsp != 0 {
		releasem(mp)
		return false
	}
	releasem(mp)
	return true
}

// shouldPushSigpanic reports whether pc should be used as sigpanic's
// return PC (pushing a frame for the call). Otherwise, it should be
// left alone so that LR is used as sigpanic's return PC, effectively
// replacing the top-most frame with sigpanic. This is used by
// preparePanic.
func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
	if pc == 0 {
		// Probably a call to a nil func. The old LR is more
		// useful in the stack trace. Not pushing the frame
		// will make the trace look like a call to sigpanic
		// instead. (Otherwise the trace will end at sigpanic
		// and we won't get to see who faulted.)
		return false
	}
	// If we don't recognize the PC as code, but we do recognize
	// the link register as code, then this assumes the panic was
	// caused by a call to non-code. In this case, we want to
	// ignore this call to make unwinding show the context.
	//
	// If we running C code, we're not going to recognize pc as a
	// Go function, so just assume it's good. Otherwise, traceback
	// may try to read a stale LR that looks like a Go code
	// pointer and wander into the woods.
	if gp.m.incgo || findfunc(pc).valid() {
		// This wasn't a bad call, so use PC as sigpanic's
		// return PC.
		return true
	}
	if findfunc(lr).valid() {
		// This was a bad call, but the LR is good, so use the
		// LR as sigpanic's return PC.
		return false
	}
	// Neither the PC or LR is good. Hopefully pushing a frame
	// will work.
	return true
}

// isAbortPC reports whether pc is the program counter at which
// runtime.abort raises a signal.
//
// It is nosplit because it's part of the isgoexception
// implementation.
//
//go:nosplit
func isAbortPC(pc uintptr) bool {
	f := findfunc(pc)
	if !f.valid() {
		return false
	}
	return f.funcID == abi.FuncID_abort
}

// For debugging only.
//
//go:noinline
//go:nosplit
func dumpPanicDeferState(where string, gp *g) {
	systemstack(func() {
		println("DUMPPANICDEFERSTATE", where)
		p := gp._panic
		d := gp._defer
		var u unwinder
		for u.init(gp, 0); u.valid(); u.next() {
			// Print frame.
			println("  frame sp=", hex(u.frame.sp), "fp=", hex(u.frame.fp), "pc=", pcName(u.frame.pc), "+", pcOff(u.frame.pc))
			// Print panic.
			for p != nil && uintptr(p.sp) == u.frame.sp {
				println("    panic", p, "sp=", p.sp, "fp=", p.fp, "arg=", p.arg, "recovered=", p.recovered, "pc=", pcName(p.pc), "+", pcOff(p.pc), "retpc=", pcName(p.retpc), "+", pcOff(p.retpc), "startsp=", p.startSP, "startPC=", hex(p.startPC), pcName(p.startPC), "+", pcOff(p.startPC))
				p = p.link
			}

			// Print linked defers.
			for d != nil && d.sp == u.frame.sp {
				println("    defer(link)", "heap=", d.heap, "rangefunc=", d.rangefunc, fnName(d.fn))
				d = d.link
			}

			// Print open-coded defers.
			// (A function is all linked or all open-coded, so we don't
			// need to interleave this loop with the one above.)
			fd := funcdata(u.frame.fn, abi.FUNCDATA_OpenCodedDeferInfo)
			if fd != nil {
				deferBitsOffset, fd := readvarintUnsafe(fd)
				m := *(*uint8)(unsafe.Pointer(u.frame.varp - uintptr(deferBitsOffset)))
				slotsOffset, fd := readvarintUnsafe(fd)
				slots := u.frame.varp - uintptr(slotsOffset)
				for i := 7; i >= 0; i-- {
					if m>>i&1 == 0 {
						continue
					}
					fn := *(*func())(unsafe.Pointer(slots + uintptr(i)*goarch.PtrSize))
					println("    defer(open)", fnName(fn))
				}
			}

		}
		if p != nil {
			println("  REMAINING PANICS!", p)
		}
		if d != nil {
			println("  REMAINING DEFERS!")
		}
	})
}

func pcName(pc uintptr) string {
	fn := findfunc(pc)
	if !fn.valid() {
		return "<unk>"
	}
	return funcname(fn)
}
func pcOff(pc uintptr) hex {
	fn := findfunc(pc)
	if !fn.valid() {
		return 0
	}
	return hex(pc - fn.entry())
}
func fnName(fn func()) string {
	return pcName(**(**uintptr)(unsafe.Pointer(&fn)))
}
