Skip to content

Commit 331614c

Browse files
tpaschalisrasky
authored andcommitted
runtime: improve error messages after allocating a stack that is too big
In the current implementation, we can observe crashes after calling debug.SetMaxStack and allocating a stack larger than 4GB since stackalloc works with 32-bit sizes. To avoid this, we define an upper limit as the largest feasible point we can grow a stack to and provide a better error message when we get a stack overflow. Fixes #41228 Change-Id: I55fb0a824f47ed9fb1fcc2445a4dfd57da9ef8d4 Reviewed-on: https://go-review.googlesource.com/c/go/+/255997 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Giovanni Bajo <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent a386802 commit 331614c

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

src/runtime/debug/garbage.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ func FreeOSMemory() {
106106
// the program crashes.
107107
// SetMaxStack returns the previous setting.
108108
// The initial setting is 1 GB on 64-bit systems, 250 MB on 32-bit systems.
109+
// There may be a system-imposed maximum stack limit regardless
110+
// of the value provided to SetMaxStack.
109111
//
110112
// SetMaxStack is useful mainly for limiting the damage done by
111113
// goroutines that enter an infinite recursion. It only limits future

src/runtime/proc.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ func main() {
128128
maxstacksize = 250000000
129129
}
130130

131+
// An upper limit for max stack size. Used to avoid random crashes
132+
// after calling SetMaxStack and trying to allocate a stack that is too big,
133+
// since stackalloc works with 32-bit sizes.
134+
maxstackceiling = 2 * maxstacksize
135+
131136
// Allow newproc to start new Ms.
132137
mainStarted = true
133138

src/runtime/stack.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,8 @@ func stackfree(stk stack) {
497497

498498
var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real
499499

500+
var maxstackceiling = maxstacksize
501+
500502
var ptrnames = []string{
501503
0: "scalar",
502504
1: "ptr",
@@ -1050,8 +1052,12 @@ func newstack() {
10501052
}
10511053
}
10521054

1053-
if newsize > maxstacksize {
1054-
print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
1055+
if newsize > maxstacksize || newsize > maxstackceiling {
1056+
if maxstacksize < maxstackceiling {
1057+
print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
1058+
} else {
1059+
print("runtime: goroutine stack exceeds ", maxstackceiling, "-byte limit\n")
1060+
}
10551061
print("runtime: sp=", hex(sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
10561062
throw("stack overflow")
10571063
}

0 commit comments

Comments
 (0)