From d91d0762c7757c12c7d5f9e2ae3f170d5bd7ba84 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 20 Aug 2020 14:22:30 -0700 Subject: runtime/debug: provide Addr method for errors from SetPanicOnFault When we're building a panic that's triggered by a memory fault when SetPanicOnFault has been called, include an Addr method. This method reports the address at which the fault occurred. Fixes #37023 RELNOTE=yes Change-Id: Idff144587d6b75070fdc861a36efec76f4ec7384 Reviewed-on: https://go-review.googlesource.com/c/go/+/249677 Run-TryBot: Keith Randall TryBot-Result: Go Bot Trust: Keith Randall Reviewed-by: Russ Cox --- src/runtime/debug/garbage.go | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/runtime/debug/garbage.go') diff --git a/src/runtime/debug/garbage.go b/src/runtime/debug/garbage.go index 785e9d4598..e36e54f12d 100644 --- a/src/runtime/debug/garbage.go +++ b/src/runtime/debug/garbage.go @@ -139,6 +139,11 @@ func SetMaxThreads(threads int) int { // manipulation of memory may cause faults at non-nil addresses in less // dramatic situations; SetPanicOnFault allows such programs to request // that the runtime trigger only a panic, not a crash. +// The runtime.Error that the runtime panics with may have an additional method: +// Addr() uintptr +// If that method exists, it returns the memory address which triggered the fault. +// The results of Addr are best-effort and the veracity of the result +// may depend on the platform. // SetPanicOnFault applies only to the current goroutine. // It returns the previous setting. func SetPanicOnFault(enabled bool) bool { -- cgit v1.3 From 331614c4daa5504ddfe35a96371cc34783d14cf1 Mon Sep 17 00:00:00 2001 From: Paschalis Tsilias Date: Fri, 18 Sep 2020 19:15:41 +0300 Subject: 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 TryBot-Result: Go Bot Trust: Giovanni Bajo Reviewed-by: Keith Randall --- src/runtime/debug/garbage.go | 2 ++ src/runtime/proc.go | 5 +++++ src/runtime/stack.go | 10 ++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src/runtime/debug/garbage.go') diff --git a/src/runtime/debug/garbage.go b/src/runtime/debug/garbage.go index e36e54f12d..00f92c3ddf 100644 --- a/src/runtime/debug/garbage.go +++ b/src/runtime/debug/garbage.go @@ -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 diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 739745aa26..f4665220ae 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -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 diff --git a/src/runtime/stack.go b/src/runtime/stack.go index 821c2e8436..613126c708 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -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 { - print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n") + 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") } -- cgit v1.3