aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/panic.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2018-06-25 18:00:43 -0400
committerAustin Clements <austin@google.com>2018-07-07 14:44:11 +0000
commit78561c4ae9b18e111ef0e25478f24e5e21dcff69 (patch)
tree5af2f88c2f326c1bd3bbeed8ad8a2aff1680448c /src/runtime/panic.go
parentd6b56bb301470c62634d1747cc155489c4e0f18a (diff)
downloadgo-78561c4ae9b18e111ef0e25478f24e5e21dcff69.tar.gz
go-78561c4ae9b18e111ef0e25478f24e5e21dcff69.zip
runtime: handle g0 stack overflows gracefully
Currently, if the runtime overflows the g0 stack on Windows, it leads to an infinite recursion: 1. Something overflows the g0 stack bounds and calls morestack. 2. morestack determines it's on the g0 stack and hence cannot grow the stack, so it calls badmorestackg0 (which prints "fatal: morestack on g0") followed by abort. 3. abort performs an INT $3, which turns into a Windows _EXCEPTION_BREAKPOINT exception. 4. This enters the Windows sigtramp, which ensures we're on the g0 stack and calls exceptionhandler. 5. exceptionhandler has a stack check prologue, so it determines that it's out of stack and calls morestack. 6. goto 2 Fix this by making the exception handler avoid stack checks until it has ruled out an abort and by blowing away the stack bounds in lastcontinuehandler before we print the final fatal traceback (which itself involves a lot of stack bounds checks). Fixes #21382. Change-Id: Ie66e91f708e18d131d97f22b43f9ac26f3aece5a Reviewed-on: https://go-review.googlesource.com/120857 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Diffstat (limited to 'src/runtime/panic.go')
-rw-r--r--src/runtime/panic.go5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 7bb7f9b90c..a5287a0b86 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -889,6 +889,11 @@ func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
// isAbortPC returns true if 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 {
return pc == funcPC(abort) || ((GOARCH == "arm" || GOARCH == "arm64") && pc == funcPC(abort)+sys.PCQuantum)
}