aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/panic.go
AgeCommit message (Collapse)Author
2018-11-02all: use "reports whether" consistently in the few places that didn'tBrad Fitzpatrick
Go documentation style for boolean funcs is to say: // Foo reports whether ... func Foo() bool (rather than "returns true if") This CL also replaces 4 uses of "iff" with the same "reports whether" wording, which doesn't lose any meaning, and will prevent people from sending typo fixes when they don't realize it's "if and only if". In the past I think we've had the typo CLs updated to just say "reports whether". So do them all at once. (Inspired by the addition of another "returns true if" in CL 146938 in fd_plan9.go) Created with: $ perl -i -npe 's/returns true if/reports whether/' $(git grep -l "returns true iff" | grep -v vendor) $ perl -i -npe 's/returns true if/reports whether/' $(git grep -l "returns true if" | grep -v vendor) Change-Id: Ided502237f5ab0d25cb625dbab12529c361a8b9f Reviewed-on: https://go-review.googlesource.com/c/147037 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-08-22runtime: fix build, rename a since-renamed hasprefix to hasPrefixBrad Fitzpatrick
I merged CL 115835 without testing it after a rebase. My bad. Change-Id: I0acc6ed78ea7d718ac2df11d509cfcf4364dfaee Reviewed-on: https://go-review.googlesource.com/130815 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Martin Möhrmann <moehrmann@google.com>
2018-07-07runtime: handle g0 stack overflows gracefullyAustin Clements
Currently, if the runtime overflows the g0 stack on Windows, it leads to an infinite recursion: 1. Something overflows the g0 stack bounds and calls morestack. 2. morestack determines it's on the g0 stack and hence cannot grow the stack, so it calls badmorestackg0 (which prints "fatal: morestack on g0") followed by abort. 3. abort performs an INT $3, which turns into a Windows _EXCEPTION_BREAKPOINT exception. 4. This enters the Windows sigtramp, which ensures we're on the g0 stack and calls exceptionhandler. 5. exceptionhandler has a stack check prologue, so it determines that it's out of stack and calls morestack. 6. goto 2 Fix this by making the exception handler avoid stack checks until it has ruled out an abort and by blowing away the stack bounds in lastcontinuehandler before we print the final fatal traceback (which itself involves a lot of stack bounds checks). Fixes #21382. Change-Id: Ie66e91f708e18d131d97f22b43f9ac26f3aece5a Reviewed-on: https://go-review.googlesource.com/120857 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
2018-06-29runtime: throw if the runtime panics with out of bounds indexIan Lance Taylor
If the runtime code panics due to a bad index or slice expression, then throw instead of panicing. This will skip calls to recover and dump the entire runtime stack trace. The runtime should never panic due to an out of bounds index, and this will help with debugging if it does. For #24991 Updates #25201 Change-Id: I85a9feded8f0de914ee1558425931853223c0514 Reviewed-on: https://go-review.googlesource.com/121515 Reviewed-by: Austin Clements <austin@google.com>
2018-06-22runtime: avoid recursive panic on bad lock countAustin Clements
Currently, if lock or unlock calls throw because the g.m.lock count is corrupted, we're unlikely to get a stack trace because startpanic_m will itself attempt to acquire a lock, causing a recursive failure. Avoid this by forcing the g.m.locks count to a sane value if it's currently bad. This might be enough to get a stack trace from #25128. Change-Id: I52d7bd4717ffae94a821f4249585f3eb6cd5aa41 Reviewed-on: https://go-review.googlesource.com/120416 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-04-30runtime: perform crashes outside systemstackElias Naur
CL 93658 moved stack trace printing inside a systemstack call to sidestep complexity in case the runtime is in a inconsistent state. Unfortunately, debuggers generating backtraces for a Go panic will be confused and come up with a technical correct but useless stack. This CL moves just the crash performing - typically a SIGABRT signal - outside the systemstack call to improve backtraces. Unfortunately, the crash function now needs to be marked nosplit and that triggers the no split stackoverflow check. To work around that, split fatalpanic in two: fatalthrow for runtime.throw and fatalpanic for runtime.gopanic. Only Go panics really needs crashes on the right stack and there is enough stack for gopanic. Example program: package main import "runtime/debug" func main() { debug.SetTraceback("crash") crash() } func crash() { panic("panic!") } Before: (lldb) bt * thread #1, name = 'simple', stop reason = signal SIGABRT * frame #0: 0x000000000044ffe4 simple`runtime.raise at <autogenerated>:1 frame #1: 0x0000000000438cfb simple`runtime.dieFromSignal(sig=<unavailable>) at signal_unix.go:424 frame #2: 0x0000000000438ec9 simple`runtime.crash at signal_unix.go:525 frame #3: 0x00000000004268f5 simple`runtime.dopanic_m(gp=<unavailable>, pc=<unavailable>, sp=<unavailable>) at panic.go:758 frame #4: 0x000000000044bead simple`runtime.fatalpanic.func1 at panic.go:657 frame #5: 0x000000000044d066 simple`runtime.systemstack at <autogenerated>:1 frame #6: 0x000000000042a980 simple at proc.go:1094 frame #7: 0x0000000000438ec9 simple`runtime.crash at signal_unix.go:525 frame #8: 0x00000000004268f5 simple`runtime.dopanic_m(gp=<unavailable>, pc=<unavailable>, sp=<unavailable>) at panic.go:758 frame #9: 0x000000000044bead simple`runtime.fatalpanic.func1 at panic.go:657 frame #10: 0x000000000044d066 simple`runtime.systemstack at <autogenerated>:1 frame #11: 0x000000000042a980 simple at proc.go:1094 frame #12: 0x00000000004268f5 simple`runtime.dopanic_m(gp=<unavailable>, pc=<unavailable>, sp=<unavailable>) at panic.go:758 frame #13: 0x000000000044bead simple`runtime.fatalpanic.func1 at panic.go:657 frame #14: 0x000000000044d066 simple`runtime.systemstack at <autogenerated>:1 frame #15: 0x000000000042a980 simple at proc.go:1094 frame #16: 0x000000000044bead simple`runtime.fatalpanic.func1 at panic.go:657 frame #17: 0x000000000044d066 simple`runtime.systemstack at <autogenerated>:1 After: (lldb) bt * thread #7, stop reason = signal SIGABRT * frame #0: 0x0000000000450024 simple`runtime.raise at <autogenerated>:1 frame #1: 0x0000000000438d1b simple`runtime.dieFromSignal(sig=<unavailable>) at signal_unix.go:424 frame #2: 0x0000000000438ee9 simple`runtime.crash at signal_unix.go:525 frame #3: 0x00000000004264e3 simple`runtime.fatalpanic(msgs=<unavailable>) at panic.go:664 frame #4: 0x0000000000425f1b simple`runtime.gopanic(e=<unavailable>) at panic.go:537 frame #5: 0x0000000000470c62 simple`main.crash at simple.go:11 frame #6: 0x0000000000470c00 simple`main.main at simple.go:6 frame #7: 0x0000000000427be7 simple`runtime.main at proc.go:198 frame #8: 0x000000000044ef91 simple`runtime.goexit at <autogenerated>:1 Updates #22716 Change-Id: Ib5fa35c13662c1dac2f1eac8b59c4a5824b98d92 Reviewed-on: https://go-review.googlesource.com/110065 Run-TryBot: Elias Naur <elias.naur@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
2018-04-26runtime: remove the dummy arg of getcallerspCherry Zhang
getcallersp is intrinsified, and so the dummy arg is no longer needed. Remove it, as well as a few dummy args that are solely to feed getcallersp. Change-Id: Ibb6c948ff9c56537042b380ac3be3a91b247aaa6 Reviewed-on: https://go-review.googlesource.com/109596 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-04-17cmd/internal/obj/arm, runtime: delete old ARM softfloat codeCherry Zhang
CL 106735 changed to the new softfloat support on GOARM=5. ARM assembly code that uses FP instructions not guarded on GOARM, if any, will break. The easiest way to fix is probably to use Go implementation on GOARM=5, like MOVB runtime·goarm(SB), R11 CMP $5, R11 BEQ arm5 ... FP instructions ... RET arm5: CALL or JMP to Go implementation Change-Id: I52fc76fac9c854ebe7c6c856c365fba35d3f560a Reviewed-on: https://go-review.googlesource.com/107475 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-03-09runtime: fix abort handling on arm64Austin Clements
The implementation of runtime.abort on arm64 currently branches to address 0, which results in a signal from PC 0, rather than from runtime.abort, so the runtime fails to recognize it as an abort. Fix runtime.abort on arm64 to read from address 0 like what other architectures do and recognize this in the signal handler. Should fix the linux/arm64 build. Change-Id: I960ab630daaeadc9190287604d4d8337b1ea3853 Reviewed-on: https://go-review.googlesource.com/99895 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
2018-03-08runtime: make throw safer to callAustin Clements
Currently, throw may grow the stack, which means whenever we call it from a context where it's not safe to grow the stack, we first have to switch to the system stack. This is pretty easy to get wrong. Fix this by making throw switch to the system stack so it doesn't grow the stack and is hence safe to call without a system stack switch at the call site. The only thing this complicates is badsystemstack itself, which would now go into an infinite loop before printing anything (previously it would also go into an infinite loop, but would at least print the error first). Fix this by making badsystemstack do a direct write and then crash hard. Change-Id: Ic5b4a610df265e47962dcfa341cabac03c31c049 Reviewed-on: https://go-review.googlesource.com/93659 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2018-03-08runtime: move unrecoverable panic handling to the system stackAustin Clements
Currently parts of unrecoverable panic handling (notably, printing panic messages) can happen on the user stack. This may grow the stack, which is generally fine, but if we're handling a runtime panic, it's better to do as little as possible in case the runtime is in an inconsistent state. Hence, this commit rearranges the handling of unrecoverable panics so that it's done entirely on the system stack. This is mostly a matter of shuffling code a bit so everything can move into a systemstack block. The one slight subtlety is in the "panic during panic" case, where we now depend on startpanic_m's caller to print the stack rather than startpanic_m itself. To make this work, startpanic_m now returns a boolean indicating that the caller should avoid trying to print any panic messages and get right to the stack trace. Since the caller is already in a position to do this, this actually simplifies things a little. Change-Id: Id72febe8c0a9fb31d9369b600a1816d65a49bfed Reviewed-on: https://go-review.googlesource.com/93658 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2018-03-06runtime: skip pointless writes in freedeferJosh Bleecher Snyder
Change-Id: I501a0e5c87ec88616c7dcdf1b723758b6df6c088 Reviewed-on: https://go-review.googlesource.com/98758 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-02-23runtime: don't check for String/Error methods in printanyIan Lance Taylor
They have either already been called by preprintpanics, or they can not be called safely because of the various conditions checked at the start of gopanic. Fixes #24059 Change-Id: I4a6233d12c9f7aaaee72f343257ea108bae79241 Reviewed-on: https://go-review.googlesource.com/96755 Reviewed-by: Austin Clements <austin@google.com>
2018-02-13runtime: avoid bad unwinding from sigpanic in C codeAustin Clements
Currently, if a sigpanic call is injected into C code, it's possible for preparePanic to leave the stack in a state where traceback can't unwind correctly past the sigpanic. Specifically, shouldPushPanic sniffs the stack to decide where to put the PC from the signal context. In the cgo case, it will find that !findfunc(pc).valid() because pc is in C code, and then it will check if the top of the stack looks like a Go PC. However, this stack slot is just in a C frame, so it could be uninitialized and contain anything, including what looks like a valid Go PC. For example, in https://build.golang.org/log/c601a18e2af24794e6c0899e05dddbb08caefc17, it sees 1c02c23a <runtime.newproc1+682>. When this condition is met, it skips putting the signal PC on the stack at all. As a result, when we later unwind from the sigpanic, we'll "successfully" but incorrectly unwind to whatever PC was in this uninitialized slot and go who knows where from there. Fix this by making shouldPushPanic assume that the signal PC is always usable if we're running C code, so we always make it appear like sigpanic's caller. This lets us be pickier again about unexpected return PCs in gentraceback. Updates #23640. Change-Id: I1e8ade24b031bd905d48e92d5e60c982e8edf160 Reviewed-on: https://go-review.googlesource.com/91137 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-02-13runtime: refactor test for pushing sigpanic frameAustin Clements
This logic is duplicated in all of the preparePanic functions. Pull it out into one architecture-independent function. Change-Id: I7ef4e78e3eda0b7be1a480fb5245fc7424fb2b4e Reviewed-on: https://go-review.googlesource.com/91255 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-01-23runtime: never allocate during an unrecoverable panicAustin Clements
Currently, startpanic_m (which prepares for an unrecoverable panic) goes out of its way to make it possible to allocate during panic handling by allocating an mcache if there isn't one. However, this is both potentially dangerous and unnecessary. Allocating an mcache is a generally complex thing to do in an already precarious situation. Specifically, it requires obtaining the heap lock, and there's evidence that this may be able to deadlock (#23360). However, it's also unnecessary because we never allocate from the unrecoverable panic path. This didn't use to be the case. The call to allocmcache was introduced long ago, in CL 7388043, where it was in preparation for separating Ms and Ps and potentially running an M without an mcache. At the time, after calling startpanic, the runtime could call String and Error methods on panicked values, which could do anything including allocating. That was generally unsafe even at the time, and CL 19792 fixed this be pre-printing panic messages before calling startpanic. As a result, we now no longer allocate after calling startpanic. This CL not only removes the allocmcache call, but goes a step further to explicitly disallow any allocation during unrecoverable panic handling, even in situations where it might be safe. This way, if panic handling ever does an allocation that would be unsafe in unusual circumstances, we'll know even if it happens during normal circumstances. This would help with debugging #23360, since the deadlock in allocmcache is currently masking the real failure. Beyond all.bash, I manually tested this change by adding panics at various points in early runtime init, signal handling, and the scheduler to check unusual panic situations. Change-Id: I85df21e2b4b20c6faf1f13fae266c9339eebc061 Reviewed-on: https://go-review.googlesource.com/88835 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-01-23runtime: don't grow the stack on sigpanic if throwsplitAustin Clements
Currently, if a _SigPanic signal arrives in a throwsplit context, nothing is stopping the runtime from injecting a call to sigpanic that may attempt to grow the stack. This will fail and, in turn, mask the real problem. Fix this by checking for throwsplit in the signal handler itself before injecting the sigpanic call. Updates #21431, where this problem is likely masking the real problem. Change-Id: I64b61ff08e8c4d6f6c0fb01315d7d5e66bf1d3e2 Reviewed-on: https://go-review.googlesource.com/87595 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-11-24runtime: tweak doc for GoexitEmmanuel Odeke
Use singular form of panic and remove the unnecessary 'however', when comparing Goexit's behavior to 'a panic' as well as what happens for deferred recovers with Goexit. Change-Id: I3116df3336fa135198f6a39cf93dbb88a0e2f46e Reviewed-on: https://go-review.googlesource.com/79755 Reviewed-by: Rob Pike <r@golang.org>
2017-10-29runtime: allow write barriers in startpanic_mAustin Clements
We're about to start tracking nowritebarrierrec through systemstack calls, which will reveal write barriers in startpanic_m prohibited by various callers. We actually can allow write barriers here because the write barrier is a no-op when we're panicking. Let the compiler know. Updates #22384. For #22460. Change-Id: Ifb3a38d3dd9a4125c278c3680f8648f987a5b0b8 Reviewed-on: https://go-review.googlesource.com/72770 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
2017-09-22runtime: remove getcallerpc argumentAustin Clements
Now that getcallerpc is a compiler intrinsic on x86 and non-x86 platforms don't need the argument, we can drop it. Sadly, this doesn't let us remove any dummy arguments since all of those cases also use getcallersp, which still takes the argument pointer, but this is at least an improvement. Change-Id: I9c34a41cf2c18cba57f59938390bf9491efb22d2 Reviewed-on: https://go-review.googlesource.com/65474 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
2017-09-22runtime: don't call lockOSThread for every cgo callIan Lance Taylor
For a trivial benchmark with a do-nothing cgo call: name old time/op new time/op delta Call-4 64.5ns ± 7% 63.0ns ± 6% -2.25% (p=0.027 n=20+16) Because Windows uses the cgocall mechanism to make system calls, and passes arguments in a struct held in the m, we need to do the lockOSThread/unlockOSThread in that code. Because deferreturn was getting a nosplit stack overflow error, change it to avoid calling typedmemmove. Updates #21827. Change-Id: I9b1d61434c44faeb29805b46b409c812c9acadc2 Reviewed-on: https://go-review.googlesource.com/64070 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: David Crawshaw <crawshaw@golang.org>
2017-08-26all: remove some double spaces from commentsDaniel Martí
Went mainly for the ones that make no sense, such as the ones mid-sentence or after commas. Change-Id: Ie245d2c19cc7428a06295635cf6a9482ade25ff0 Reviewed-on: https://go-review.googlesource.com/57293 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-08-18all: unindent some big chunks of codeDaniel Martí
Found with mvdan.cc/unindent. Prioritized the ones with the biggest wins for now. Change-Id: I2b032e45cdd559fc9ed5b1ee4c4de42c4c92e07b Reviewed-on: https://go-review.googlesource.com/56470 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-06-05runtime: delay exiting while panic is running deferred functionsIan Lance Taylor
Try to avoid a race between the main goroutine exiting and a panic occurring. Don't try too hard, to avoid hanging. Updates #3934 Fixes #20018 Change-Id: I57a02b6d795d2a61f1cadd137ce097145280ece7 Reviewed-on: https://go-review.googlesource.com/41052 Reviewed-by: Austin Clements <austin@google.com>
2017-02-14runtime: remove stack barriersAustin Clements
Now that we don't rescan stacks, stack barriers are unnecessary. This removes all of the code and structures supporting them as well as tests that were specifically for stack barriers. Updates #17503. Change-Id: Ia29221730e0f2bbe7beab4fa757f31a032d9690c Reviewed-on: https://go-review.googlesource.com/36620 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-12-08all: make spelling consistentBrad Fitzpatrick
Fixes #17938 Change-Id: Iad12155f4976846bd4a9a53869f89e40e5b3deb3 Reviewed-on: https://go-review.googlesource.com/34147 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2016-10-21runtime: fix call* signatures and deferArgs with siz=0Austin Clements
This commit fixes two bizarrely related bugs: 1. The signatures for the call* functions were wrong, indicating that they had only two pointer arguments instead of three. We didn't notice because the call* functions are defined by a macro expansion, which go vet doesn't see. 2. deferArgs on a defer object with a zero-sized frame returned a pointer just past the end of the allocated object, which is illegal in Go (and can cause the "sweep increased allocation count" crashes). In a fascinating twist, these two bugs canceled each other out, which is why I'm fixing them together. The pointer returned by deferArgs is used in only two ways: as an argument to memmove and as an argument to reflectcall. memmove is NOSPLIT, so the argument was unobservable. reflectcall immediately tail calls one of the call* functions, which are not NOSPLIT, but the deferArgs pointer just happened to be the third argument that was accidentally marked as a scalar. Hence, when the garbage collector scanned the stack, it didn't see the bad pointer as a pointer. I believe this was all ultimately benign. In principle, stack growth during the reflectcall could fail to update the args pointer, but it never points to the stack, so it never needs to be updated. Also in principle, the garbage collector could fail to mark the args object because of the incorrect call* signatures, but in all calls to reflectcall (including the ones spelled "call" in the reflect package) the args object is kept live by the calling stack. Change-Id: Ic932c79d5f4382be23118fdd9dba9688e9169e28 Reviewed-on: https://go-review.googlesource.com/31654 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-10-19sync: throw, not panic, for unlock of unlocked mutexRuss Cox
The panic leaves the lock in an unusable state. Trying to panic with a usable state makes the lock significantly less efficient and scalable (see early CL patch sets and discussion). Instead, use runtime.throw, which will crash the program directly. In general throw is reserved for when the runtime detects truly serious, unrecoverable problems. This problem is certainly serious, and, without a significant performance hit, is unrecoverable. Fixes #13879. Change-Id: I41920d9e2317270c6f909957d195bd8b68177f8d Reviewed-on: https://go-review.googlesource.com/31359 Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-05runtime: avoid endless loop if printing the panic value panicsIan Lance Taylor
Change-Id: I56de359a5ccdc0a10925cd372fa86534353c6ca0 Reviewed-on: https://go-review.googlesource.com/30358 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-26runtime: optimize defer codeAustin Clements
This optimizes deferproc and deferreturn in various ways. The most important optimization is that it more carefully arranges to prevent preemption or stack growth. Currently we do this by switching to the system stack on every deferproc and every deferreturn. While we need to be on the system stack for the slow path of allocating and freeing defers, in the common case we can fit in the nosplit stack. Hence, this change pushes the system stack switch down into the slow paths and makes everything now exposed to the user stack nosplit. This also eliminates the need for various acquirem/releasem pairs, since we are now preventing preemption by preventing stack split checks. As another smaller optimization, we special case the common cases of zero-sized and pointer-sized defer frames to respectively skip the copy and perform the copy in line instead of calling memmove. This speeds up the runtime defer benchmark by 42%: name old time/op new time/op delta Defer-4 75.1ns ± 1% 43.3ns ± 1% -42.31% (p=0.000 n=8+10) In reality, this speeds up defer by about 2.2X. The two benchmarks below compare a Lock/defer Unlock pair (DeferLock) with a Lock/Unlock pair (NoDeferLock). NoDeferLock establishes a baseline cost, so these two benchmarks together show that this change reduces the overhead of defer from 61.4ns to 27.9ns. name old time/op new time/op delta DeferLock-4 77.4ns ± 1% 43.9ns ± 1% -43.31% (p=0.000 n=10+10) NoDeferLock-4 16.0ns ± 0% 15.9ns ± 0% -0.39% (p=0.000 n=9+8) This also shaves 34ns off cgo calls: name old time/op new time/op delta CgoNoop-4 122ns ± 1% 88.3ns ± 1% -27.72% (p=0.000 n=8+9) Updates #14939, #16051. Change-Id: I2baa0dea378b7e4efebbee8fca919a97d5e15f38 Reviewed-on: https://go-review.googlesource.com/29656 Reviewed-by: Keith Randall <khr@golang.org>
2016-09-15cmd/compile, runtime: remove throwreturnMatthew Dempsky
Change-Id: If8d27cf1cd8d650ed0ba332448d3174d80b6b0ca Reviewed-on: https://go-review.googlesource.com/29217 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-08runtime: simplify getargpJosh Bleecher Snyder
Change-Id: I9ed62e8a6d8b9204c18748efd7845adabf3460b9 Reviewed-on: https://go-review.googlesource.com/28775 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-05-05runtime: print signal name in panic, if name is knownEmmanuel Odeke
Adds a small function signame that infers a signal name from the signal table, otherwise will fallback to using hex(sig) as previously. No signal table is present for Windows hence it will always print the hex value. Sample code and new result: ```go package main import ( "fmt" "time" ) func main() { defer func() { if err := recover(); err != nil { fmt.Printf("err=%v\n", err) } }() ticker := time.Tick(1e9) for { <-ticker } } ``` ```shell $ go run main.go & $ kill -11 <pid> fatal error: unexpected signal during runtime execution [signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0xc71db] ... ``` Fixes #13969 Change-Id: Ie6be312eb766661f1cea9afec352b73270f27f9d Reviewed-on: https://go-review.googlesource.com/22753 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-04-20runtime: simplify mallocgc flag argumentKeith Randall
mallocgc can calculate noscan itself. The only remaining flag argument is needzero, so we just make that a boolean arg. Fixes #15379 Change-Id: I839a70790b2a0c9dbcee2600052bfbd6c8148e20 Reviewed-on: https://go-review.googlesource.com/22290 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-04runtime: fix off-by-one error finding module for PCIan Lance Taylor
Also fix compiler-invoked panics to avoid a confusing "malloc deadlock" crash if they are invoked while executing the runtime. Fixes #14599. Change-Id: I89436abcbf3587901909abbdca1973301654a76e Reviewed-on: https://go-review.googlesource.com/20219 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-03-02all: single space after period.Brad Fitzpatrick
The tree's pretty inconsistent about single space vs double space after a period in documentation. Make it consistently a single space, per earlier decisions. This means contributors won't be confused by misleading precedence. This CL doesn't use go/doc to parse. It only addresses // comments. It was generated with: $ perl -i -npe 's,^(\s*// .+[a-z]\.) +([A-Z]),$1 $2,' $(git grep -l -E '^\s*//(.+\.) +([A-Z])') $ go test go/doc -update Change-Id: Iccdb99c37c797ef1f804a94b22ba5ee4b500c4f7 Reviewed-on: https://go-review.googlesource.com/20022 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Dave Day <djd@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-02-21runtime: when crash with panic, call user Error/String methods before ↵Shenghou Ma
freezing the world Fixes #14432. Change-Id: I0a92ef86de95de39217df9a664d8034ef685a906 Reviewed-on: https://go-review.googlesource.com/19792 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Minux Ma <minux@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-11-10runtime: break atomics out into package runtime/internal/atomicMichael Matloob
This change breaks out most of the atomics functions in the runtime into package runtime/internal/atomic. It adds some basic support in the toolchain for runtime packages, and also modifies linux/arm atomics to remove the dependency on the runtime's mutex. The mutexes have been replaced with spinlocks. all trybots are happy! In addition to the trybots, I've tested on the darwin/arm64 builder, on the darwin/arm builder, and on a ppc64le machine. Change-Id: I6698c8e3cf3834f55ce5824059f44d00dc8e3c2f Reviewed-on: https://go-review.googlesource.com/14204 Run-TryBot: Michael Matloob <matloob@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
2015-10-30runtime: introduce GOTRACEBACK=single, now the defaultRuss Cox
Abandon (but still support) the old numbering system. GOTRACEBACK=none is old 0 GOTRACEBACK=single is the new behavior GOTRACEBACK=all is old 1 GOTRACEBACK=system is old 2 GOTRACEBACK=crash is unchanged See doc comment change in runtime1.go for details. Filed #13107 to decide whether to change default back to GOTRACEBACK=all for Go 1.6 release. If you run into programs where printing only the current goroutine omits needed information, please add details in a comment on that issue. Fixes #12366. Change-Id: I82ca8b99b5d86dceb3f7102d38d2659d45dbe0db Reviewed-on: https://go-review.googlesource.com/16512 Reviewed-by: Austin Clements <austin@google.com>
2015-10-19runtime: remove a redundant nil pointer check.Aaron Jacobs
It appears this was made possible by commit 89f185f; before that, g was not dereferenced above. Change-Id: I70bc571d924b36351392fd4c13d681e938cfb573 Reviewed-on: https://go-review.googlesource.com/16033 Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-10-18runtime: add a constant for the smallest possible stack frameMichael Hudson-Doyle
Shared libraries on ppc64le will require a larger minimum stack frame (because the ABI mandates that the TOC pointer is available at 24(R1)). So to prepare for this, make a constant for the fixed part of a stack and use that where necessary. Change-Id: I447949f4d725003bb82e7d2cf7991c1bca5aa887 Reviewed-on: https://go-review.googlesource.com/15523 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-10-16runtime: merge panic1.go into panic.goNodir Turakulov
A TODO to merge is removed from panic1.go. The rest is appended to panic.go Updates #12952 Change-Id: Ied4382a455abc20bc2938e34d031802e6b4baf8b Reviewed-on: https://go-review.googlesource.com/15905 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
2015-10-15runtime: use unsafe.Pointer(x) instead of (unsafe.Pointer)(x)Matthew Dempsky
This isn't C anymore. No binary change to pkg/linux_amd64/runtime.a. Change-Id: I24d66b0f5ac888f432b874aac684b1395e7c8345 Reviewed-on: https://go-review.googlesource.com/15903 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2015-08-06runtime: call goexit1 instead of goexitAustin Clements
Currently, runtime.Goexit() calls goexit()—the goroutine exit stub—to terminate the goroutine. This *mostly* works, but can cause a "leftover stack barriers" panic if the following happens: 1. Goroutine A has a reasonably large stack. 2. The garbage collector scan phase runs and installs stack barriers in A's stack. The top-most stack barrier happens to fall at address X. 3. Goroutine A unwinds the stack far enough to be a candidate for stack shrinking, but not past X. 4. Goroutine A calls runtime.Goexit(), which calls goexit(), which calls goexit1(). 5. The garbage collector enters mark termination. 6. Goroutine A is preempted right at the prologue of goexit1() and performs a stack shrink, which calls gentraceback. gentraceback stops as soon as it sees goexit on the stack, which is only two frames up at this point, even though there may really be many frames above it. More to the point, the stack barrier at X is above the goexit frame, so gentraceback never sees that stack barrier. At the end of gentraceback, it checks that it saw all of the stack barriers and panics because it didn't see the one at X. The fix is simple: call goexit1, which actually implements the process of exiting a goroutine, rather than goexit, the exit stub. To make sure this doesn't happen again in the future, we also add an argument to the stub prototype of goexit so you really, really have to want to call it in order to call it. We were able to reliably reproduce the above sequence with a fair amount of awful code inserted at the right places in the runtime, but chose to change the goexit prototype to ensure this wouldn't happen again rather than pollute the runtime with ugly testing code. Change-Id: Ifb6fb53087e09a252baddadc36eebf954468f2a8 Reviewed-on: https://go-review.googlesource.com/13323 Reviewed-by: Russ Cox <rsc@golang.org>
2015-06-11all: fix misprints in commentsAinar Garipov
These were found by grepping the comments from the go code and feeding the output to aspell. Change-Id: Id734d6c8d1938ec3c36bd94a4dbbad577e3ad395 Reviewed-on: https://go-review.googlesource.com/10941 Reviewed-by: Aamir Khan <syst3m.w0rm@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2015-05-11runtime: remove wbshadow modeRuss Cox
The write barrier shadow heap was very useful for developing the write barriers initially, but it's no longer used, clunky, and dragging the rest of the implementation down. The gccheckmark mode will find bugs due to missed barriers when they result in missed marks; wbshadow mode found the missed barriers more aggressively, but it required an entire separate copy of the heap. The gccheckmark mode requires no extra memory, making it more useful in practice. Compared to previous CL: name old mean new mean delta BinaryTree17 5.91s × (0.96,1.06) 5.72s × (0.97,1.03) -3.12% (p=0.000) Fannkuch11 4.32s × (1.00,1.00) 4.36s × (1.00,1.00) +0.91% (p=0.000) FmtFprintfEmpty 89.0ns × (0.93,1.10) 86.6ns × (0.96,1.11) ~ (p=0.077) FmtFprintfString 298ns × (0.98,1.06) 283ns × (0.99,1.04) -4.90% (p=0.000) FmtFprintfInt 286ns × (0.98,1.03) 283ns × (0.98,1.04) -1.09% (p=0.032) FmtFprintfIntInt 498ns × (0.97,1.06) 480ns × (0.99,1.02) -3.65% (p=0.000) FmtFprintfPrefixedInt 408ns × (0.98,1.02) 396ns × (0.99,1.01) -3.00% (p=0.000) FmtFprintfFloat 587ns × (0.98,1.01) 562ns × (0.99,1.01) -4.34% (p=0.000) FmtManyArgs 1.94µs × (0.99,1.02) 1.89µs × (0.99,1.01) -2.85% (p=0.000) GobDecode 15.8ms × (0.98,1.03) 15.7ms × (0.99,1.02) ~ (p=0.251) GobEncode 12.0ms × (0.96,1.09) 11.8ms × (0.98,1.03) -1.87% (p=0.024) Gzip 648ms × (0.99,1.01) 647ms × (0.99,1.01) ~ (p=0.688) Gunzip 143ms × (1.00,1.01) 143ms × (1.00,1.01) ~ (p=0.203) HTTPClientServer 90.3µs × (0.98,1.01) 89.1µs × (0.99,1.02) -1.30% (p=0.000) JSONEncode 31.6ms × (0.99,1.01) 31.7ms × (0.98,1.02) ~ (p=0.219) JSONDecode 107ms × (1.00,1.01) 111ms × (0.99,1.01) +3.58% (p=0.000) Mandelbrot200 6.03ms × (1.00,1.01) 6.01ms × (1.00,1.00) ~ (p=0.077) GoParse 6.53ms × (0.99,1.03) 6.54ms × (0.99,1.02) ~ (p=0.585) RegexpMatchEasy0_32 161ns × (1.00,1.01) 161ns × (0.98,1.05) ~ (p=0.948) RegexpMatchEasy0_1K 541ns × (0.99,1.01) 559ns × (0.98,1.01) +3.32% (p=0.000) RegexpMatchEasy1_32 138ns × (1.00,1.00) 137ns × (0.99,1.01) -0.55% (p=0.001) RegexpMatchEasy1_1K 887ns × (0.99,1.01) 878ns × (0.99,1.01) -0.98% (p=0.000) RegexpMatchMedium_32 253ns × (0.99,1.01) 252ns × (0.99,1.01) -0.39% (p=0.001) RegexpMatchMedium_1K 72.8µs × (1.00,1.00) 72.7µs × (1.00,1.00) ~ (p=0.485) RegexpMatchHard_32 3.85µs × (1.00,1.01) 3.85µs × (1.00,1.01) ~ (p=0.283) RegexpMatchHard_1K 117µs × (1.00,1.01) 117µs × (1.00,1.00) ~ (p=0.175) Revcomp 922ms × (0.97,1.08) 903ms × (0.98,1.05) -2.15% (p=0.021) Template 126ms × (0.99,1.01) 126ms × (0.99,1.01) ~ (p=0.943) TimeParse 628ns × (0.99,1.01) 634ns × (0.99,1.01) +0.92% (p=0.000) TimeFormat 668ns × (0.99,1.01) 698ns × (0.98,1.03) +4.53% (p=0.000) It's nice that the microbenchmarks are the ones helped the most, because those were the ones hurt the most by the conversion from 4-bit to 2-bit heap bitmaps. This CL brings the overall effect of that process to (compared to CL 9706 patch set 1): name old mean new mean delta BinaryTree17 5.87s × (0.94,1.09) 5.72s × (0.97,1.03) -2.57% (p=0.011) Fannkuch11 4.32s × (1.00,1.00) 4.36s × (1.00,1.00) +0.87% (p=0.000) FmtFprintfEmpty 89.1ns × (0.95,1.16) 86.6ns × (0.96,1.11) ~ (p=0.090) FmtFprintfString 283ns × (0.98,1.02) 283ns × (0.99,1.04) ~ (p=0.681) FmtFprintfInt 284ns × (0.98,1.04) 283ns × (0.98,1.04) ~ (p=0.620) FmtFprintfIntInt 486ns × (0.98,1.03) 480ns × (0.99,1.02) -1.27% (p=0.002) FmtFprintfPrefixedInt 400ns × (0.99,1.02) 396ns × (0.99,1.01) -0.84% (p=0.001) FmtFprintfFloat 566ns × (0.99,1.01) 562ns × (0.99,1.01) -0.80% (p=0.000) FmtManyArgs 1.91µs × (0.99,1.02) 1.89µs × (0.99,1.01) -1.10% (p=0.000) GobDecode 15.5ms × (0.98,1.05) 15.7ms × (0.99,1.02) +1.55% (p=0.005) GobEncode 11.9ms × (0.97,1.03) 11.8ms × (0.98,1.03) -0.97% (p=0.048) Gzip 648ms × (0.99,1.01) 647ms × (0.99,1.01) ~ (p=0.627) Gunzip 143ms × (1.00,1.00) 143ms × (1.00,1.01) ~ (p=0.482) HTTPClientServer 89.2µs × (0.99,1.02) 89.1µs × (0.99,1.02) ~ (p=0.740) JSONEncode 32.3ms × (0.97,1.06) 31.7ms × (0.98,1.02) -1.95% (p=0.002) JSONDecode 106ms × (0.99,1.01) 111ms × (0.99,1.01) +4.22% (p=0.000) Mandelbrot200 6.02ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~ (p=0.417) GoParse 6.57ms × (0.97,1.06) 6.54ms × (0.99,1.02) ~ (p=0.404) RegexpMatchEasy0_32 162ns × (1.00,1.00) 161ns × (0.98,1.05) ~ (p=0.088) RegexpMatchEasy0_1K 561ns × (0.99,1.02) 559ns × (0.98,1.01) -0.47% (p=0.034) RegexpMatchEasy1_32 145ns × (0.95,1.04) 137ns × (0.99,1.01) -5.56% (p=0.000) RegexpMatchEasy1_1K 864ns × (0.99,1.04) 878ns × (0.99,1.01) +1.57% (p=0.000) RegexpMatchMedium_32 255ns × (0.99,1.04) 252ns × (0.99,1.01) -1.43% (p=0.001) RegexpMatchMedium_1K 73.9µs × (0.98,1.04) 72.7µs × (1.00,1.00) -1.55% (p=0.004) RegexpMatchHard_32 3.92µs × (0.98,1.04) 3.85µs × (1.00,1.01) -1.80% (p=0.003) RegexpMatchHard_1K 120µs × (0.98,1.04) 117µs × (1.00,1.00) -2.13% (p=0.001) Revcomp 936ms × (0.95,1.08) 903ms × (0.98,1.05) -3.58% (p=0.002) Template 130ms × (0.98,1.04) 126ms × (0.99,1.01) -2.98% (p=0.000) TimeParse 638ns × (0.98,1.05) 634ns × (0.99,1.01) ~ (p=0.198) TimeFormat 674ns × (0.99,1.01) 698ns × (0.98,1.03) +3.69% (p=0.000) Change-Id: Ia0e9b50b1d75a3c0c7556184cd966305574fe07c Reviewed-on: https://go-review.googlesource.com/9706 Reviewed-by: Rick Hudson <rlh@golang.org>
2015-04-20runtime: replace func-based write barrier skipping with type-basedRuss Cox
This CL revises CL 7504 to use explicitly uintptr types for the struct fields that are going to be updated sometimes without write barriers. The result is that the fields are now updated *always* without write barriers. This approach has two important properties: 1) Now the GC never looks at the field, so if the missing reference could cause a problem, it will do so all the time, not just when the write barrier is missed at just the right moment. 2) Now a write barrier never happens for the field, avoiding the (correct) detection of inconsistent write barriers when GODEBUG=wbshadow=1. Change-Id: Iebd3962c727c0046495cc08914a8dc0808460e0e Reviewed-on: https://go-review.googlesource.com/9019 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-03-05runtime: apply comments from CL 3742Russ Cox
I asked for this in CL 3742 and it was ignored. Change-Id: I30ad05f87c7d9eccb11df7e19288e3ed2c7e2e3f Reviewed-on: https://go-review.googlesource.com/6930 Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
2015-03-04runtime: bound defer pools (try 2)Dmitry Vyukov
The unbounded list-based defer pool can grow infinitely. This can happen if a goroutine routinely allocates a defer; then blocks on one P; and then unblocked, scheduled and frees the defer on another P. The scenario was reported on golang-nuts list. We've been here several times. Any unbounded local caches are bad and grow to infinite size. This change introduces central defer pool; local pools become fixed-size with the only purpose of amortizing accesses to the central pool. Freedefer now executes on system stack to not consume nosplit stack space. Change-Id: I1a27695838409259d1586a0adfa9f92bccf7ceba Reviewed-on: https://go-review.googlesource.com/3967 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
2015-02-04Revert "runtime: bound defer pools"Russ Cox
This reverts commit 805907115352801a54f987fc9079251b478cce3f. Conflicts: src/runtime/proc1.go (resolved by hand) Change-Id: Ic62e3e802f0007ff9012b37bc5fd41fcafc153d0 Reviewed-on: https://go-review.googlesource.com/3885 Reviewed-by: Dmitry Vyukov <dvyukov@google.com>