aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/stack.c')
-rw-r--r--src/pkg/runtime/stack.c19
1 files changed, 18 insertions, 1 deletions
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);
+}