From 757e0de89f80e89626cc8b7d6e670c0e5ea7f192 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 15 Aug 2013 22:34:06 -0400 Subject: runtime: impose stack size limit The goal is to stop only those programs that would keep going and run the machine out of memory, but before they do that. 1 GB on 64-bit, 250 MB on 32-bit. That seems implausibly large, and it can be adjusted. Fixes #2556. Fixes #4494. Fixes #5173. R=khr, r, dvyukov CC=golang-dev https://golang.org/cl/12541052 --- src/pkg/runtime/stack.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src/pkg/runtime/stack.c') diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c index 812ba17e2d..dd823705da 100644 --- a/src/pkg/runtime/stack.c +++ b/src/pkg/runtime/stack.c @@ -176,13 +176,17 @@ runtime·oldstack(void) gp->stackguard = top->stackguard; gp->stackguard0 = gp->stackguard; - if(top->free != 0) + if(top->free != 0) { + gp->stacksize -= top->free; runtime·stackfree(old, top->free); + } gp->status = oldstatus; runtime·gogo(&gp->sched); } +uintptr runtime·maxstacksize = 1<<20; // enough until runtime.main sets it for real + // Called from runtime·newstackcall or from runtime·morestack when a new // stack segment is needed. Allocate a new stack big enough for // m->moreframesize bytes, copy m->moreargsize bytes to the new frame, @@ -285,6 +289,11 @@ runtime·newstack(void) if(framesize < StackMin) framesize = StackMin; framesize += StackSystem; + gp->stacksize += framesize; + if(gp->stacksize > runtime·maxstacksize) { + runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize); + runtime·throw("stack overflow"); + } stk = runtime·stackalloc(framesize); top = (Stktop*)(stk+framesize-sizeof(*top)); free = framesize; @@ -353,3 +362,11 @@ runtime·gostartcallfn(Gobuf *gobuf, FuncVal *fv) { runtime·gostartcall(gobuf, fv->fn, fv); } + +void +runtime∕debug·setMaxStack(intgo in, intgo out) +{ + out = runtime·maxstacksize; + runtime·maxstacksize = in; + FLUSH(&out); +} -- cgit v1.3