aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-10-13 10:44:57 -0400
committerAustin Clements <austin@google.com>2016-10-17 18:56:09 +0000
commit687d9d5d78f8a2d09b2052e73be0c83740e17fda (patch)
treed8aa74b0a3aea918b939be3aad6fda4c5d4e0946 /src/runtime
parent0ba3c607dfcc90072191375d57c4059be1ae96c7 (diff)
downloadgo-687d9d5d78f8a2d09b2052e73be0c83740e17fda.tar.xz
runtime: print a message on bad morestack
If morestack runs on the g0 or gsignal stack, it currently performs some abort operation that typically produces a signal (e.g., it does an INT $3 on x86). This is useful if you're running in a debugger, but if you're not, the runtime tries to trap this signal, which is likely to send the program into a deeper spiral of collapse and lead to very confusing diagnostic output. Help out people trying to debug without a debugger by making morestack print an informative message before blowing up. Change-Id: I2814c64509b137bfe20a00091d8551d18c2c4749 Reviewed-on: https://go-review.googlesource.com/31133 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/asm_386.s6
-rw-r--r--src/runtime/asm_amd64.s6
-rw-r--r--src/runtime/asm_amd64p32.s6
-rw-r--r--src/runtime/asm_arm.s8
-rw-r--r--src/runtime/asm_arm64.s6
-rw-r--r--src/runtime/asm_mips64x.s6
-rw-r--r--src/runtime/asm_ppc64x.s6
-rw-r--r--src/runtime/asm_s390x.s6
-rw-r--r--src/runtime/proc.go18
9 files changed, 52 insertions, 16 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
index 56d495aede..4ef738eacb 100644
--- a/src/runtime/asm_386.s
+++ b/src/runtime/asm_386.s
@@ -354,13 +354,15 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0
MOVL g_m(BX), BX
MOVL m_g0(BX), SI
CMPL g(CX), SI
- JNE 2(PC)
+ JNE 3(PC)
+ CALL runtime·badmorestackg0(SB)
INT $3
// Cannot grow signal stack.
MOVL m_gsignal(BX), SI
CMPL g(CX), SI
- JNE 2(PC)
+ JNE 3(PC)
+ CALL runtime·badmorestackgsignal(SB)
INT $3
// Called from f.
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 8d992188de..34da3bda9f 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -331,13 +331,15 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0
MOVQ g_m(BX), BX
MOVQ m_g0(BX), SI
CMPQ g(CX), SI
- JNE 2(PC)
+ JNE 3(PC)
+ CALL runtime·badmorestackg0(SB)
INT $3
// Cannot grow signal stack (m->gsignal).
MOVQ m_gsignal(BX), SI
CMPQ g(CX), SI
- JNE 2(PC)
+ JNE 3(PC)
+ CALL runtime·badmorestackgsignal(SB)
INT $3
// Called from f.
diff --git a/src/runtime/asm_amd64p32.s b/src/runtime/asm_amd64p32.s
index 0b42c666ae..4e3c0cd2b6 100644
--- a/src/runtime/asm_amd64p32.s
+++ b/src/runtime/asm_amd64p32.s
@@ -249,13 +249,15 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0
// Cannot grow scheduler stack (m->g0).
MOVL m_g0(BX), SI
CMPL g(CX), SI
- JNE 2(PC)
+ JNE 3(PC)
+ CALL runtime·badmorestackg0(SB)
MOVL 0, AX
// Cannot grow signal stack (m->gsignal).
MOVL m_gsignal(BX), SI
CMPL g(CX), SI
- JNE 2(PC)
+ JNE 3(PC)
+ CALL runtime·badmorestackgsignal(SB)
MOVL 0, AX
// Called from f.
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index d768060af2..0c7d580163 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -281,12 +281,16 @@ TEXT runtime·morestack(SB),NOSPLIT,$-4-0
MOVW g_m(g), R8
MOVW m_g0(R8), R4
CMP g, R4
- BL.EQ runtime·abort(SB)
+ BNE 3(PC)
+ BL runtime·badmorestackg0(SB)
+ B runtime·abort(SB)
// Cannot grow signal stack (m->gsignal).
MOVW m_gsignal(R8), R4
CMP g, R4
- BL.EQ runtime·abort(SB)
+ BNE 3(PC)
+ BL runtime·badmorestackgsignal(SB)
+ B runtime·abort(SB)
// Called from f.
// Set g->sched to context in f.
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s
index c46569f68c..bd2b18385e 100644
--- a/src/runtime/asm_arm64.s
+++ b/src/runtime/asm_arm64.s
@@ -256,13 +256,15 @@ TEXT runtime·morestack(SB),NOSPLIT,$-8-0
MOVD g_m(g), R8
MOVD m_g0(R8), R4
CMP g, R4
- BNE 2(PC)
+ BNE 3(PC)
+ BL runtime·badmorestackg0(SB)
B runtime·abort(SB)
// Cannot grow signal stack (m->gsignal).
MOVD m_gsignal(R8), R4
CMP g, R4
- BNE 2(PC)
+ BNE 3(PC)
+ BL runtime·badmorestackgsignal(SB)
B runtime·abort(SB)
// Called from f.
diff --git a/src/runtime/asm_mips64x.s b/src/runtime/asm_mips64x.s
index 138181833c..e29522367d 100644
--- a/src/runtime/asm_mips64x.s
+++ b/src/runtime/asm_mips64x.s
@@ -231,12 +231,14 @@ TEXT runtime·morestack(SB),NOSPLIT,$-8-0
// Cannot grow scheduler stack (m->g0).
MOVV g_m(g), R7
MOVV m_g0(R7), R8
- BNE g, R8, 2(PC)
+ BNE g, R8, 3(PC)
+ JAL runtime·badmorestackg0(SB)
JAL runtime·abort(SB)
// Cannot grow signal stack (m->gsignal).
MOVV m_gsignal(R7), R8
- BNE g, R8, 2(PC)
+ BNE g, R8, 3(PC)
+ JAL runtime·badmorestackgsignal(SB)
JAL runtime·abort(SB)
// Called from f.
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index 8b5ea45082..251dc1b564 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -284,13 +284,15 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
MOVD g_m(g), R7
MOVD m_g0(R7), R8
CMP g, R8
- BNE 2(PC)
+ BNE 3(PC)
+ BL runtime·badmorestackg0(SB)
BL runtime·abort(SB)
// Cannot grow signal stack (m->gsignal).
MOVD m_gsignal(R7), R8
CMP g, R8
- BNE 2(PC)
+ BNE 3(PC)
+ BL runtime·badmorestackgsignal(SB)
BL runtime·abort(SB)
// Called from f.
diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s
index 70e3b5e859..9ed4d91868 100644
--- a/src/runtime/asm_s390x.s
+++ b/src/runtime/asm_s390x.s
@@ -279,13 +279,15 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
// Cannot grow scheduler stack (m->g0).
MOVD g_m(g), R7
MOVD m_g0(R7), R8
- CMPBNE g, R8, 2(PC)
+ CMPBNE g, R8, 3(PC)
+ BL runtime·badmorestackg0(SB)
BL runtime·abort(SB)
// Cannot grow signal stack (m->gsignal).
MOVD m_gsignal(R7), R8
CMP g, R8
- BNE 2(PC)
+ BNE 3(PC)
+ BL runtime·badmorestackgsignal(SB)
BL runtime·abort(SB)
// Called from f.
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index cb0004d233..937135961a 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -381,6 +381,24 @@ func badreflectcall() {
panic(plainError("arg size to reflect.call more than 1GB"))
}
+var badmorestackg0Msg = "fatal: morestack on g0\n"
+
+//go:nosplit
+//go:nowritebarrierrec
+func badmorestackg0() {
+ sp := stringStructOf(&badmorestackg0Msg)
+ write(2, sp.str, int32(sp.len))
+}
+
+var badmorestackgsignalMsg = "fatal: morestack on gsignal\n"
+
+//go:nosplit
+//go:nowritebarrierrec
+func badmorestackgsignal() {
+ sp := stringStructOf(&badmorestackgsignalMsg)
+ write(2, sp.str, int32(sp.len))
+}
+
func lockedOSThread() bool {
gp := getg()
return gp.lockedm != nil && gp.m.lockedg != nil