aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/stack.c
AgeCommit message (Collapse)Author
2013-11-01[release-branch.go1.2] runtime: relax preemption assertion during stack splitAndrew Gerrand
««« CL 18740044 / 1a8903f0a577 runtime: relax preemption assertion during stack split The case can happen when starttheworld is calling acquirep to get things moving again and acquirep gets preempted. The stack trace is in golang.org/issue/6644. It is difficult to build a short test case for this, but the person who reported issue 6644 confirms that this solves the problem. Fixes #6644. R=golang-dev, r CC=golang-dev https://golang.org/cl/18740044 »»» R=golang-dev CC=golang-dev https://golang.org/cl/20460044
2013-09-12runtime, cmd/gc, cmd/ld: ignore method wrappers in recoverRuss Cox
Bug #1: Issue 5406 identified an interesting case: defer iface.M() may end up calling a wrapper that copies an indirect receiver from the iface value and then calls the real M method. That's two calls down, not just one, and so recover() == nil always in the real M method, even during a panic. [For the purposes of this entire discussion, a wrapper's implementation is a function containing an ordinary call, not the optimized tail call form that is somtimes possible. The tail call does not create a second frame, so it is already handled correctly.] Fix this bug by introducing g->panicwrap, which counts the number of bytes on current stack segment that are due to wrapper calls that should not count against the recover check. All wrapper functions must now adjust g->panicwrap up on entry and back down on exit. This adds slightly to their expense; on the x86 it is a single instruction at entry and exit; on the ARM it is three. However, the alternative is to make a call to recover depend on being able to walk the stack, which I very much want to avoid. We have enough problems walking the stack for garbage collection and profiling. Also, if performance is critical in a specific case, it is already faster to use a pointer receiver and avoid this kind of wrapper entirely. Bug #2: The old code, which did not consider the possibility of two calls, already contained a check to see if the call had split its stack and so the panic-created segment was one behind the current segment. In the wrapper case, both of the two calls might split their stacks, so the panic-created segment can be two behind the current segment. Fix this by propagating the Stktop.panic flag forward during stack splits instead of looking backward during recover. Fixes #5406. R=golang-dev, iant CC=golang-dev https://golang.org/cl/13367052
2013-09-06runtime: account for all sys memory in MemStatsDmitriy Vyukov
Currently lots of sys allocations are not accounted in any of XxxSys, including GC bitmap, spans table, GC roots blocks, GC finalizer blocks, iface table, netpoll descriptors and more. Up to ~20% can unaccounted. This change introduces 2 new stats: GCSys and OtherSys for GC metadata and all other misc allocations, respectively. Also ensures that all XxxSys indeed sum up to Sys. All sys memory allocation functions require the stat for accounting, so that it's impossible to miss something. Also fix updating of mcache_sys/inuse, they were not updated after deallocation. test/bench/garbage/parser before: Sys 670064344 HeapSys 610271232 StackSys 65536 MSpanSys 14204928 MCacheSys 16384 BuckHashSys 1439992 after: Sys 670064344 HeapSys 610271232 StackSys 65536 MSpanSys 14188544 MCacheSys 16384 BuckHashSys 3194304 GCSys 39198688 OtherSys 3129656 Fixes #5799. R=rsc, dave, alex.brainman CC=golang-dev https://golang.org/cl/12946043
2013-08-22runtime: do not trigger GC on g0Dmitriy Vyukov
GC acquires worldsema, which is a goroutine-level semaphore which parks goroutines. g0 can not be parked. Fixes #6193. R=khr, khr CC=golang-dev https://golang.org/cl/12880045
2013-08-19runtime: don't run finalizers if we're still on the g0 stack.Keith Randall
R=golang-dev, rsc, dvyukov, khr CC=golang-dev https://golang.org/cl/11386044
2013-08-15runtime: impose stack size limitRuss Cox
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
2013-08-02runtime: reimplement reflect.call to not use stack splitting.Keith Randall
R=golang-dev, r, khr, rsc CC=golang-dev https://golang.org/cl/12053043
2013-08-02runtime: in newstack, double-check calling goroutineRuss Cox
Checking this condition helped me find the arm problem last night. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/12267043
2013-07-29runtime: do not split stacks in syscall statusDmitriy Vyukov
Split stack checks (morestack) corrupt g->sched, but g->sched must be preserved consistent for GC/traceback. The change implements runtime.notetsleepg function, which does entersyscall/exitsyscall and is carefully arranged to not call any split functions in between. R=rsc CC=golang-dev https://golang.org/cl/11575044
2013-07-26runtime: refactor mallocgcDmitriy Vyukov
Make it accept type, combine flags. Several reasons for the change: 1. mallocgc and settype must be atomic wrt GC 2. settype is called from only one place now 3. it will help performance (eventually settype functionality must be combined with markallocated) 4. flags are easier to read now (no mallocgc(sz, 0, 1, 0) anymore) R=golang-dev, iant, nightlyone, rsc, dave, khr, bradfitz, r CC=golang-dev https://golang.org/cl/10136043
2013-07-19runtime: preempt long-running goroutinesDmitriy Vyukov
If a goroutine runs for more than 10ms, preempt it. Update #543. R=rsc CC=golang-dev https://golang.org/cl/10796043
2013-07-17runtime: more reliable preemptionDmitriy Vyukov
Currently preemption signal g->stackguard0==StackPreempt can be lost if it is received when preemption is disabled (e.g. m->lock!=0). This change duplicates the preemption signal in g->preempt and restores g->stackguard0 when preemption is enabled. Update #543. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/10792043
2013-07-12cmd/ld: fix large stack split for preempt checkRuss Cox
If the stack frame size is larger than the known-unmapped region at the bottom of the address space, then the stack split prologue cannot use the usual condition: SP - size >= stackguard because SP - size may wrap around to a very large number. Instead, if the stack frame is large, the prologue tests: SP - stackguard >= size (This ends up being a few instructions more expensive, so we don't do it always.) Preemption requests register by setting stackguard to a very large value, so that the first test (SP - size >= stackguard) cannot possibly succeed. Unfortunately, that same very large value causes a wraparound in the second test (SP - stackguard >= size), making it succeed incorrectly. To avoid *that* wraparound, we have to amend the test: stackguard != StackPreempt && SP - stackguard >= size This test is only used for functions with large frames, which essentially always split the stack, so the cost of the few instructions is noise. This CL and CL 11085043 together fix the known issues with preemption, at the beginning of a function, so we will be able to try turning it on again. R=ken2 CC=golang-dev https://golang.org/cl/11205043
2013-06-28runtime: preempt goroutines for GCDmitriy Vyukov
The last patch for preemptive scheduler, with this change stoptheworld issues preemption requests every 100us. Update #543. R=golang-dev, daniel.morsing, rsc CC=golang-dev https://golang.org/cl/10264044
2013-06-27runtime: use gp->sched.sp for stack overflow checkRuss Cox
On x86 it is a few words lower on the stack than m->morebuf.sp so it is a more precise check. Enabling the check requires recording a valid gp->sched in reflect.call too. This is a good thing in general, since it will make stack traces during reflect.call work better, and it may be useful for preemption too. R=dvyukov CC=golang-dev https://golang.org/cl/10709043
2013-06-28runtime: fix goroutine status corruptionDmitriy Vyukov
runtime.entersyscall() sets g->status = Gsyscall, then calls runtime.lock() which causes stack split. runtime.newstack() resets g->status to Grunning. This will lead to crash during GC (world is not stopped) or GC will scan stack incorrectly. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/10696043
2013-06-27runtime: record proper goroutine state during stack splitRuss Cox
Until now, the goroutine state has been scattered during the execution of newstack and oldstack. It's all there, and those routines know how to get back to a working goroutine, but other pieces of the system, like stack traces, do not. If something does interrupt the newstack or oldstack execution, the rest of the system can't understand the goroutine. For example, if newstack decides there is an overflow and calls throw, the stack tracer wouldn't dump the goroutine correctly. For newstack to save a useful state snapshot, it needs to be able to rewind the PC in the function that triggered the split back to the beginning of the function. (The PC is a few instructions in, just after the call to morestack.) To make that possible, we change the prologues to insert a jmp back to the beginning of the function after the call to morestack. That is, the prologue used to be roughly: TEXT myfunc check for split jmpcond nosplit call morestack nosplit: sub $xxx, sp Now an extra instruction is inserted after the call: TEXT myfunc start: check for split jmpcond nosplit call morestack jmp start nosplit: sub $xxx, sp The jmp is not executed directly. It is decoded and simulated by runtime.rewindmorestack to discover the beginning of the function, and then the call to morestack returns directly to the start label instead of to the jump instruction. So logically the jmp is still executed, just not by the cpu. The prologue thus repeats in the case of a function that needs a stack split, but against the cost of the split itself, the extra few instructions are noise. The repeated prologue has the nice effect of making a stack split double-check that the new stack is big enough: if morestack happens to return on a too-small stack, we'll now notice before corruption happens. The ability for newstack to rewind to the beginning of the function should help preemption too. If newstack decides that it was called for preemption instead of a stack split, it now has the goroutine state correctly paused if rescheduling is needed, and when the goroutine can run again, it can return to the start label on its original stack and re-execute the split check. Here is an example of a split stack overflow showing the full trace, without any special cases in the stack printer. (This one was triggered by making the split check incorrect.) runtime: newstack framesize=0x0 argsize=0x18 sp=0x6aebd0 stack=[0x6b0000, 0x6b0fa0] morebuf={pc:0x69f5b sp:0x6aebd8 lr:0x0} sched={pc:0x68880 sp:0x6aebd0 lr:0x0 ctxt:0x34e700} runtime: split stack overflow: 0x6aebd0 < 0x6b0000 fatal error: runtime: split stack overflow goroutine 1 [stack split]: runtime.mallocgc(0x290, 0x100000000, 0x1) /Users/rsc/g/go/src/pkg/runtime/zmalloc_darwin_amd64.c:21 fp=0x6aebd8 runtime.new() /Users/rsc/g/go/src/pkg/runtime/zmalloc_darwin_amd64.c:682 +0x5b fp=0x6aec08 go/build.(*Context).Import(0x5ae340, 0xc210030c71, 0xa, 0xc2100b4380, 0x1b, ...) /Users/rsc/g/go/src/pkg/go/build/build.go:424 +0x3a fp=0x6b00a0 main.loadImport(0xc210030c71, 0xa, 0xc2100b4380, 0x1b, 0xc2100b42c0, ...) /Users/rsc/g/go/src/cmd/go/pkg.go:249 +0x371 fp=0x6b01a8 main.(*Package).load(0xc21017c800, 0xc2100b42c0, 0xc2101828c0, 0x0, 0x0, ...) /Users/rsc/g/go/src/cmd/go/pkg.go:431 +0x2801 fp=0x6b0c98 main.loadPackage(0x369040, 0x7, 0xc2100b42c0, 0x0) /Users/rsc/g/go/src/cmd/go/pkg.go:709 +0x857 fp=0x6b0f80 ----- stack segment boundary ----- main.(*builder).action(0xc2100902a0, 0x0, 0x0, 0xc2100e6c00, 0xc2100e5750, ...) /Users/rsc/g/go/src/cmd/go/build.go:539 +0x437 fp=0x6b14a0 main.(*builder).action(0xc2100902a0, 0x0, 0x0, 0xc21015b400, 0x2, ...) /Users/rsc/g/go/src/cmd/go/build.go:528 +0x1d2 fp=0x6b1658 main.(*builder).test(0xc2100902a0, 0xc210092000, 0x0, 0x0, 0xc21008ff60, ...) /Users/rsc/g/go/src/cmd/go/test.go:622 +0x1b53 fp=0x6b1f68 ----- stack segment boundary ----- main.runTest(0x5a6b20, 0xc21000a020, 0x2, 0x2) /Users/rsc/g/go/src/cmd/go/test.go:366 +0xd09 fp=0x6a5cf0 main.main() /Users/rsc/g/go/src/cmd/go/main.go:161 +0x4f9 fp=0x6a5f78 runtime.main() /Users/rsc/g/go/src/pkg/runtime/proc.c:183 +0x92 fp=0x6a5fa0 runtime.goexit() /Users/rsc/g/go/src/pkg/runtime/proc.c:1266 fp=0x6a5fa8 And here is a seg fault during oldstack: SIGSEGV: segmentation violation PC=0x1b2a6 runtime.oldstack() /Users/rsc/g/go/src/pkg/runtime/stack.c:159 +0x76 runtime.lessstack() /Users/rsc/g/go/src/pkg/runtime/asm_amd64.s:270 +0x22 goroutine 1 [stack unsplit]: fmt.(*pp).printArg(0x2102e64e0, 0xe5c80, 0x2102c9220, 0x73, 0x0, ...) /Users/rsc/g/go/src/pkg/fmt/print.go:818 +0x3d3 fp=0x221031e6f8 fmt.(*pp).doPrintf(0x2102e64e0, 0x12fb20, 0x2, 0x221031eb98, 0x1, ...) /Users/rsc/g/go/src/pkg/fmt/print.go:1183 +0x15cb fp=0x221031eaf0 fmt.Sprintf(0x12fb20, 0x2, 0x221031eb98, 0x1, 0x1, ...) /Users/rsc/g/go/src/pkg/fmt/print.go:234 +0x67 fp=0x221031eb40 flag.(*stringValue).String(0x2102c9210, 0x1, 0x0) /Users/rsc/g/go/src/pkg/flag/flag.go:180 +0xb3 fp=0x221031ebb0 flag.(*FlagSet).Var(0x2102f6000, 0x293d38, 0x2102c9210, 0x143490, 0xa, ...) /Users/rsc/g/go/src/pkg/flag/flag.go:633 +0x40 fp=0x221031eca0 flag.(*FlagSet).StringVar(0x2102f6000, 0x2102c9210, 0x143490, 0xa, 0x12fa60, ...) /Users/rsc/g/go/src/pkg/flag/flag.go:550 +0x91 fp=0x221031ece8 flag.(*FlagSet).String(0x2102f6000, 0x143490, 0xa, 0x12fa60, 0x0, ...) /Users/rsc/g/go/src/pkg/flag/flag.go:563 +0x87 fp=0x221031ed38 flag.String(0x143490, 0xa, 0x12fa60, 0x0, 0x161950, ...) /Users/rsc/g/go/src/pkg/flag/flag.go:570 +0x6b fp=0x221031ed80 testing.init() /Users/rsc/g/go/src/pkg/testing/testing.go:-531 +0xbb fp=0x221031edc0 strings_test.init() /Users/rsc/g/go/src/pkg/strings/strings_test.go:1115 +0x62 fp=0x221031ef70 main.init() strings/_test/_testmain.go:90 +0x3d fp=0x221031ef78 runtime.main() /Users/rsc/g/go/src/pkg/runtime/proc.c:180 +0x8a fp=0x221031efa0 runtime.goexit() /Users/rsc/g/go/src/pkg/runtime/proc.c:1269 fp=0x221031efa8 goroutine 2 [runnable]: runtime.MHeap_Scavenger() /Users/rsc/g/go/src/pkg/runtime/mheap.c:438 runtime.goexit() /Users/rsc/g/go/src/pkg/runtime/proc.c:1269 created by runtime.main /Users/rsc/g/go/src/pkg/runtime/proc.c:166 rax 0x23ccc0 rbx 0x23ccc0 rcx 0x0 rdx 0x38 rdi 0x2102c0170 rsi 0x221032cfe0 rbp 0x221032cfa0 rsp 0x7fff5fbff5b0 r8 0x2102c0120 r9 0x221032cfa0 r10 0x221032c000 r11 0x104ce8 r12 0xe5c80 r13 0x1be82baac718 r14 0x13091135f7d69200 r15 0x0 rip 0x1b2a6 rflags 0x10246 cs 0x2b fs 0x0 gs 0x0 Fixes #5723. R=r, dvyukov, go.peter.90, dave, iant CC=golang-dev https://golang.org/cl/10360048
2013-06-15runtime: remove unused moreframesize_minalloc fieldDmitriy Vyukov
It was used to request large stack segment for GC when it was running not on g0. Now GC is running on g0 with large stack, and it is not needed anymore. R=golang-dev, dave CC=golang-dev https://golang.org/cl/10242045
2013-06-12runtime: add lr, ctxt, ret to GobufRuss Cox
Add gostartcall and gostartcallfn. The old gogocall = gostartcall + gogo. The old gogocallfn = gostartcallfn + gogo. R=dvyukov, minux.ma CC=golang-dev https://golang.org/cl/10036044
2013-06-12runtime: adjust traceback / garbage collector boundaryRuss Cox
The garbage collection routine addframeroots is duplicating logic in the traceback routine that calls it, sometimes correctly, sometimes incorrectly, sometimes incompletely. Pass necessary information to addframeroots instead of deriving it anew. Should make addframeroots significantly more robust. It's certainly smaller. Also try to standardize on uintptr for saved pc, sp values. Will make CL 10036044 trivial. R=golang-dev, dave, dvyukov CC=golang-dev https://golang.org/cl/10169045
2013-06-03runtime: add stackguard0 to GDmitriy Vyukov
This is part of preemptive scheduler. stackguard0 is checked in split stack checks and can be set to StackPreempt. stackguard is not set to StackPreempt (holds the original value). R=golang-dev, daniel.morsing, iant CC=golang-dev https://golang.org/cl/9875043
2013-05-25runtime: update comment on stack allocatorDmitriy Vyukov
R=golang-dev, r CC=golang-dev https://golang.org/cl/9665046
2013-02-26runtime: fix stack cache typosAnthony Martin
R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/7370050
2013-02-22cmd/6g, cmd/8g: switch to DX for indirect call blockRuss Cox
runtime: add context argument to gogocall Too many other things use AX, and at least one (stack zeroing) cannot be moved onto a different register. Use the less special DX instead. Preparation for step 2 of http://golang.org/s/go11func. Nothing interesting here, just split out so that we can see it's correct before moving on. R=ken2 CC=golang-dev https://golang.org/cl/7395050
2013-02-21cmd/gc, reflect, runtime: switch to indirect func value representationRuss Cox
Step 1 of http://golang.org/s/go11func. R=golang-dev, r, daniel.morsing, remyoudompheng CC=golang-dev https://golang.org/cl/7393045
2013-02-15runtime: fix debug outputDmitriy Vyukov
R=golang-dev, minux.ma CC=golang-dev https://golang.org/cl/7312101
2013-02-14runtime: move stack management related code to stack.cDmitriy Vyukov
No code changes. This is mainly in preparation to scheduler changes, oldstack/newstack are not related to scheduling. R=golang-dev, minux.ma, rsc CC=golang-dev https://golang.org/cl/7311085