// Hide call from linker nosplit analysis.
MOVL $runtime·badsystemstack(SB), AX
CALL AX
+ INT $3
/*
* support for morestack
// Bad: g is not gsignal, not g0, not curg. What is it?
MOVQ $runtime·badsystemstack(SB), AX
CALL AX
+ INT $3
/*
// Hide call from linker nosplit analysis.
MOVL $runtime·badsystemstack(SB), AX
CALL AX
+ INT $3
/*
* support for morestack
// Hide call from linker nosplit analysis.
MOVW $runtime·badsystemstack(SB), R0
BL (R0)
+ B runtime·abort(SB)
switch:
// save our state in g->sched. Pretend to
// Hide call from linker nosplit analysis.
MOVD $runtime·badsystemstack(SB), R3
BL (R3)
+ B runtime·abort(SB)
switch:
// save our state in g->sched. Pretend to
// Hide call from linker nosplit analysis.
MOVV $runtime·badsystemstack(SB), R4
JAL (R4)
+ JAL runtime·abort(SB)
switch:
// save our state in g->sched. Pretend to
// Hide call from linker nosplit analysis.
MOVW $runtime·badsystemstack(SB), R4
JAL (R4)
+ JAL runtime·abort(SB)
switch:
// save our state in g->sched. Pretend to
MOVD $runtime·badsystemstack(SB), R12
MOVD R12, CTR
BL (CTR)
+ BL runtime·abort(SB)
switch:
// save our state in g->sched. Pretend to
// Hide call from linker nosplit analysis.
MOVD $runtime·badsystemstack(SB), R3
BL (R3)
+ BL runtime·abort(SB)
switch:
// save our state in g->sched. Pretend to
if i >= off && bits&bitPointer != 0 {
v := *(*unsafe.Pointer)(add(src, i))
if cgoIsGoPointer(v) {
- systemstack(func() {
- throw(cgoWriteBarrierFail)
- })
+ throw(cgoWriteBarrierFail)
}
}
hbits = hbits.next()
if bits&1 != 0 {
v := *(*unsafe.Pointer)(add(src, i))
if cgoIsGoPointer(v) {
- systemstack(func() {
- throw(cgoWriteBarrierFail)
- })
+ throw(cgoWriteBarrierFail)
}
}
}
//go:nosplit
func throw(s string) {
- print("fatal error: ", s, "\n")
+ // 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: ", s, "\n")
+ })
gp := getg()
if gp.m.throwing == 0 {
gp.m.throwing = 1
// GC time to finish and change the state to oldval.
for i := 0; !atomic.Cas(&gp.atomicstatus, oldval, newval); i++ {
if oldval == _Gwaiting && gp.atomicstatus == _Grunnable {
- systemstack(func() {
- throw("casgstatus: waiting for Gwaiting but is Grunnable")
- })
+ throw("casgstatus: waiting for Gwaiting but is Grunnable")
}
// Help GC if needed.
// if gp.preemptscan && !gp.gcworkdone && (oldval == _Grunning || oldval == _Gsyscall) {
_g_.m.locks++ // see comment in entersyscall
if getcallersp(unsafe.Pointer(&dummy)) > _g_.syscallsp {
- // throw calls print which may try to grow the stack,
- // but throwsplit == true so the stack can not be grown;
- // use systemstack to avoid that possible problem.
- systemstack(func() {
- throw("exitsyscall: syscall frame is no longer valid")
- })
+ throw("exitsyscall: syscall frame is no longer valid")
}
_g_.waitsince = 0
oldp := _g_.m.p.ptr()
if exitsyscallfast() {
if _g_.m.mcache == nil {
- systemstack(func() {
- throw("lost mcache")
- })
+ throw("lost mcache")
}
if trace.enabled {
if oldp != _g_.m.p.ptr() || _g_.m.syscalltick != _g_.m.p.ptr().syscalltick {
mcall(exitsyscall0)
if _g_.m.mcache == nil {
- systemstack(func() {
- throw("lost mcache")
- })
+ throw("lost mcache")
}
// Scheduler returned, so we're allowed to run now.
//go:nosplit
func morestackc() {
- systemstack(func() {
- throw("attempt to execute system stack code on user stack")
- })
+ throw("attempt to execute system stack code on user stack")
}
//go:noescape
func systemstack(fn func())
+var badsystemstackMsg = "fatal: systemstack called from unexpected goroutine"
+
+//go:nosplit
+//go:nowritebarrierrec
func badsystemstack() {
- throw("systemstack called from unexpected goroutine")
+ sp := stringStructOf(&badsystemstackMsg)
+ write(2, sp.str, int32(sp.len))
}
// memclrNoHeapPointers clears n bytes starting at ptr.