mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Giovanni Bajo <rasky@develer.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
a3868028ac
commit
331614c4da
3 changed files with 15 additions and 2 deletions
|
|
@ -106,6 +106,8 @@ func FreeOSMemory() {
|
|||
// the program crashes.
|
||||
// SetMaxStack returns the previous setting.
|
||||
// The initial setting is 1 GB on 64-bit systems, 250 MB on 32-bit systems.
|
||||
// There may be a system-imposed maximum stack limit regardless
|
||||
// of the value provided to SetMaxStack.
|
||||
//
|
||||
// SetMaxStack is useful mainly for limiting the damage done by
|
||||
// goroutines that enter an infinite recursion. It only limits future
|
||||
|
|
|
|||
|
|
@ -128,6 +128,11 @@ func main() {
|
|||
maxstacksize = 250000000
|
||||
}
|
||||
|
||||
// An upper limit for max stack size. Used to avoid random crashes
|
||||
// after calling SetMaxStack and trying to allocate a stack that is too big,
|
||||
// since stackalloc works with 32-bit sizes.
|
||||
maxstackceiling = 2 * maxstacksize
|
||||
|
||||
// Allow newproc to start new Ms.
|
||||
mainStarted = true
|
||||
|
||||
|
|
|
|||
|
|
@ -497,6 +497,8 @@ func stackfree(stk stack) {
|
|||
|
||||
var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real
|
||||
|
||||
var maxstackceiling = maxstacksize
|
||||
|
||||
var ptrnames = []string{
|
||||
0: "scalar",
|
||||
1: "ptr",
|
||||
|
|
@ -1050,8 +1052,12 @@ func newstack() {
|
|||
}
|
||||
}
|
||||
|
||||
if newsize > maxstacksize {
|
||||
if newsize > maxstacksize || newsize > maxstackceiling {
|
||||
if maxstacksize < maxstackceiling {
|
||||
print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
|
||||
} else {
|
||||
print("runtime: goroutine stack exceeds ", maxstackceiling, "-byte limit\n")
|
||||
}
|
||||
print("runtime: sp=", hex(sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
|
||||
throw("stack overflow")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue