aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/panic.go
AgeCommit message (Collapse)Author
2023-01-19internal/godebug: export non-default-behavior counters in runtime/metricsRuss Cox
Allow GODEBUG users to report how many times a setting resulted in non-default behavior. Record non-default-behaviors for all existing GODEBUGs. Also rework tests to ensure that runtime is in sync with runtime/metrics.All, and generate docs mechanically from metrics.All. For #56986. Change-Id: Iefa1213e2a5c3f19ea16cd53298c487952ef05a4 Reviewed-on: https://go-review.googlesource.com/c/go/+/453618 TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-01-19runtime: replace panic(nil) with panic(new(runtime.PanicNilError))Russ Cox
Long ago we decided that panic(nil) was too unlikely to bother making a special case for purposes of recover. Unfortunately, it has turned out not to be a special case. There are many examples of code in the Go ecosystem where an author has written panic(nil) because they want to panic and don't care about the panic value. Using panic(nil) in this case has the unfortunate behavior of making recover behave as though the goroutine isn't panicking. As a result, code like: func f() { defer func() { if err := recover(); err != nil { log.Fatalf("panicked! %v", err) } }() call1() call2() } looks like it guarantees that call2 has been run any time f returns, but that turns out not to be strictly true. If call1 does panic(nil), then f returns "successfully", having recovered the panic, but without calling call2. Instead you have to write something like: func f() { done := false defer func() { if err := recover(); !done { log.Fatalf("panicked! %v", err) } }() call1() call2() done = true } which defeats nearly the whole point of recover. No one does this, with the result that almost all uses of recover are subtly broken. One specific broken use along these lines is in net/http, which recovers from panics in handlers and sends back an HTTP error. Users discovered in the early days of Go that panic(nil) was a convenient way to jump out of a handler up to the serving loop without sending back an HTTP error. This was a bug, not a feature. Go 1.8 added panic(http.ErrAbortHandler) as a better way to access the feature. Any lingering code that uses panic(nil) to abort an HTTP handler without a failure message should be changed to use http.ErrAbortHandler. Programs that need the old, unintended behavior from net/http or other packages can set GODEBUG=panicnil=1 to stop the run-time error. Uses of recover that want to detect panic(nil) in new programs can check for recover returning a value of type *runtime.PanicNilError. Because the new GODEBUG is used inside the runtime, we can't import internal/godebug, so there is some new machinery to cross-connect those in this CL, to allow a mutable GODEBUG setting. That won't be necessary if we add any other mutable GODEBUG settings in the future. The CL also corrects the handling of defaulted GODEBUG values in the runtime, for #56986. Fixes #25448. Change-Id: I2b39c7e83e4f7aa308777dabf2edae54773e03f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/461956 Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Russ Cox <rsc@golang.org>
2022-09-19cmd/compile: implement slice-to-array conversionsMatthew Dempsky
The conversion T(x) is implemented as *(*T)(x). Accordingly, runtime panic messages for (*T)(x) are made more general. Fixes #46505. Change-Id: I76317c0878b6a5908299506d392eed50d7ef6523 Reviewed-on: https://go-review.googlesource.com/c/go/+/430415 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Jenny Rakoczy <jenny@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org>
2022-09-06runtime: remove unused parameter on runOpenDeferFrameDaniel Martí
Found via unparam. Change-Id: I21126405beaf0be84e14ac165ecb68aeb0c9c823 Reviewed-on: https://go-review.googlesource.com/c/go/+/427014 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: hopehook <hopehook@golangcn.org>
2022-08-12runtime: convert panicking to atomic typeMichael Pratt
For #53821. Change-Id: I93409f377881a3c029b41b0f1fbcef5e21091f2f Reviewed-on: https://go-review.googlesource.com/c/go/+/419438 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2022-08-12runtime: convert runningPanicDefers to atomic typeMichael Pratt
For #53821. Change-Id: Ib48a1f2ff85d667c86dbd0b7662efab5a0abd837 Reviewed-on: https://go-review.googlesource.com/c/go/+/419437 Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
2022-08-02runtime: trivial replacements of _g_ in remaining filesMichael Pratt
Change-Id: I24d299b345bda1c9d6fa7876d4f03c05b8c1156d Reviewed-on: https://go-review.googlesource.com/c/go/+/418587 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Michael Pratt <mpratt@google.com> Reviewed-by: Austin Clements <austin@google.com>
2022-08-02runtime: clean up dopanic_mMichael Pratt
gp is a user G running on the same M as getg(), so it is a fine proxy for gp.m. Change-Id: I9aa1dd283ecf28878eeedd7da4ded5c901809832 Reviewed-on: https://go-review.googlesource.com/c/go/+/418576 Run-TryBot: Michael Pratt <mpratt@google.com> Reviewed-by: Austin Clements <austin@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2022-08-02runtime: clean up canpanicMichael Pratt
* The gp argument to canpanic is always equivalent to getg(), so no need to pass it at all. * gp must not be nil or _g_.m would have crashed, so no need to check for nil. * Use acquirem to better reason about preemption. Change-Id: Ic7dc8dc1e56ab4c1644965f6aeba16807cdb2df4 Reviewed-on: https://go-review.googlesource.com/c/go/+/418575 Reviewed-by: Austin Clements <austin@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Michael Pratt <mpratt@google.com>
2022-05-16runtime: mark panicshift and panicdivide as //go:yeswritebarrierrecMatthew Dempsky
When compiling package runtime, cmd/compile logically has two copies of package runtime: the actual source files being compiled, and the internal description used for emitting compiler-generated calls. Notably, CL 393715 will cause the compiler's write barrier validation to start recognizing that compiler-generated calls are actually calls to the corresponding functions from the source package. And today, there are some code paths in nowritebarrierrec code paths that actually end up generating code to call panicshift or panicdivide. In preparation, this CL marks those functions as //go:yeswritebarrierrec. We probably want to actually cleanup those code paths to avoid these calls actually (e.g., explicitly convert shift count expressions to an unsigned integer type). But for now, this at least unblocks CL 393715 while preserving the status quo. Updates #51734. Change-Id: I01f89adb72466c0260a9cd363e3e09246e39cff9 Reviewed-on: https://go-review.googlesource.com/c/go/+/406316 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2022-05-13runtime: add go:yeswritebarrierrec to panic functionsDavid Chase
Panic avoids any write barriers in the runtime by checking first and throwing if called inappropriately, so it is "okay". Adding this annotation repairs recursive write barrier checking, which becomes more thorough when the local package naming convention is changed from "" to the actual package name. This CL is a prerequisite for a pending code cleanup, https://go-review.googlesource.com/c/go/+/393715 Updates #51734. Change-Id: If831a3598c6c8cd37a8e9ba269f822cd81464a13 Reviewed-on: https://go-review.googlesource.com/c/go/+/405900 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: David Chase <drchase@google.com>
2022-04-28runtime: simply user throws, expand runtime throwsMichael Pratt
This gives explicit names to the possible states of throwing (-1, 0, 1). m.throwing is now one of: throwTypeOff: not throwing, previously == 0 throwTypeUser: user throw, previously == -1 throwTypeRuntime: runtime throw, previously == 1 For runtime throws, we now always include frame metadata and system goroutines regardless of GOTRACEBACK to aid in debugging the runtime. For user throws, we no longer include frame metadata or runtime frames, unless GOTRACEBACK=system or higher. For #51485. Change-Id: If252e2377a0b6385ce7756b937929be4273a56c0 Reviewed-on: https://go-review.googlesource.com/c/go/+/390421 Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Austin Clements <austin@google.com>
2022-04-28runtime: differentiate "user" and "system" throwsMichael Pratt
"User" throws are throws due to some invariant broken by the application. "System" throws are due to some invariant broken by the runtime, environment, etc (i.e., not the fault of the application). This CL sends "user" throws through the new fatal. Currently this function is identical to throw, but with a different name to clearly differentiate the throw type in the stack trace, and hopefully be a bit more clear to users what it means. This CL changes a few categories of throw to fatal: 1. Concurrent map read/write. 2. Deadlock detection. 3. Unlock of unlocked sync.Mutex. 4. Inconsistent results from syscall.AllThreadsSyscall. "Thread exhaustion" and "out of memory" (usually address space full) throws are additional throws that are arguably the fault of user code, but I've left off for now because there is no specific invariant that they have broken to get into these states. For #51485 Change-Id: I713276a6c290fd34a6563e6e9ef378669d74ae32 Reviewed-on: https://go-review.googlesource.com/c/go/+/390420 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Michael Pratt <mpratt@google.com>
2022-04-15runtime: don't discard value from panic while panickinghopehook
In issue #17671, there are a endless loop if printing the panic value panics, CL 30358 has fixed that. As issue #52257 pointed out, above change should not discard the value from panic while panicking. With this CL, when we recover from a panic in error.Error() or stringer.String(), and the recovered value is string, then we can print it normally. Fixes #52257 Change-Id: Icfcc4a1a390635de405eea04904b4607ae9e3055 Reviewed-on: https://go-review.googlesource.com/c/go/+/399874 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2022-04-05all: separate doc comment from //go: directivesRuss Cox
A future change to gofmt will rewrite // Doc comment. //go:foo to // Doc comment. // //go:foo Apply that change preemptively to all comments (not necessarily just doc comments). For #51082. Change-Id: Iffe0285418d1e79d34526af3520b415a12203ca9 Reviewed-on: https://go-review.googlesource.com/c/go/+/384260 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-13all: gofmt -w -r 'interface{} -> any' srcRuss Cox
And then revert the bootstrap cmd directories and certain testdata. And adjust tests as needed. Not reverting the changes in std that are bootstrapped, because some of those changes would appear in API docs, and we want to use any consistently. Instead, rewrite 'any' to 'interface{}' in cmd/dist for those directories when preparing the bootstrap copy. A few files changed as a result of running gofmt -w not because of interface{} -> any but because they hadn't been updated for the new //go:build lines. Fixes #49884. Change-Id: Ie8045cba995f65bd79c694ec77a1b3d1fe01bb09 Reviewed-on: https://go-review.googlesource.com/c/go/+/368254 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
2021-11-09runtime: revert recent Windows crashdump changesJason A. Donenfeld
Recent changes to runtime enabled crashdumps, which under some circumstances apparently might result in memory being uploaded to Microsoft. A change like this should go through the proper proposals process where we can discuss how to gate it and what all of its implications are. This reverts CL 307372 and its cleanup CL 360617. Change-Id: If2e74015899d746831da40546c82eacacdf739e1 Reviewed-on: https://go-review.googlesource.com/c/go/+/362454 Trust: Jason A. Donenfeld <Jason@zx2c4.com> Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2021-10-29runtime: do not add open defer entry above a started open defer entryDan Scales
Fix two defer bugs related to adding/removing open defer entries. The bugs relate to the way that we add and remove open defer entries from the defer chain. At the point of a panic, when we want to start processing defer entries in order during the panic process, we need to add entries to the defer chain for stack frames with open defers, since the normal fast-defer code does not add these entries. We do this by calling addOneOpenDeferFrame() at the beginning of each time around the defer loop in gopanic(). Those defer entries get sorted with other open and non-open-coded defer frames. However, the tricky part is that we also need to remove defer entries if they end not being needed because of a recover (which means we are back to executing the defer code inline at function exits). But we need to deal with multiple panics and in-process defers on the stack, so we can't just remove all open-coded defers from the the defer chain during a recover. The fix (and new invariant) is that we should not add any open-coded defers to the defer chain that are higher up the stack than an open-coded defer that is in progress. We know that open-coded defer will still be run until completed, and when it is completed, then a more outer frame will be added (if there is one). This fits with existing code in gopanic that only removes open-coded defer entries up to any defer in progress. These bugs were because of the previous inconsistency between adding and removing open defer entries, which meant that stale defer entries could be left on the list, in these unusual cases with both recursive panics plus multiple independent (non-nested) cases of panic & recover. The test for #48898 was difficult to add to defer_test.go (while keeping the failure mode), so I added as a go/test/fixedbug test instead. Fixes #43920 Updates #43941 Fixes #48898 Change-Id: I593b77033e08c33094315abf8089fbc4cab07376 Reviewed-on: https://go-review.googlesource.com/c/go/+/356011 Trust: Dan Scales <danscales@google.com> Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Austin Clements <austin@google.com>
2021-10-29runtime: enable crash dump creation on WindowsZhi Zheng
This change provides ability to create dumps on Windows that can be used by "dlv core" command. Currently only full dumps can be correctly read by Delve. Below are the steps to create and use the dumps. 1. Configure Windows OS to collect dumps before running the program. Instructions on how to do the configuration are here: https://docs.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps. In order for Delve to read the dump, set the DumpType to full dump, i.e. DumpType=2. 2. Go program only generates dumps when the environment variable GOTRACEBACK is set to crash. Run command "set GOTRACEBACK=crash" before running the program. 3. Dump files will be generated in %LOCALAPPDATA%\CrashDumps 4. Use Delve command "dlv core" to open the dump, e.g.: "dlv core a.exe a.exe.3840.dmp". Fixes #20498 Change-Id: Ib9aa82e7aea9da19594dc49348876997b24e9600 Reviewed-on: https://go-review.googlesource.com/c/go/+/307372 Run-TryBot: Alessandro Arzilli <alessandro.arzilli@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Patrik Nyblom <pnyb@google.com> Trust: Alex Brainman <alex.brainman@gmail.com>
2021-10-26runtime: rename _m_ to mp [generated]Michael Pratt
_g_, _p_, and _m_ are primarily vestiges of the C version of the runtime, while today we prefer Go-style variable names (generally gp, pp, and mp). This change replaces all remaining uses of _m_ with mp. There are very few remaining and all replacements are trivial. [git-generate] cd src/runtime rf 'mv canpanic._m_ canpanic.mp' GOOS=solaris \ rf 'mv semasleep._m_ semasleep.mp' GOOS=aix GOARCH=ppc64 \ rf 'mv semasleep._m_ semasleep.mp' Change-Id: I83690f7b4d4dc57557963100e9a2560ff343f3e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/307813 Trust: Michael Pratt <mpratt@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-09-27runtime: convert _func.entry to a methodJosh Bleecher Snyder
A subsequent change will alter the semantics of _func.entry. To make that change obvious and clear, change _func.entry to a method, and rename the field to _func.entryPC. Change-Id: I05d66b54d06c5956d4537b0729ddf4290c3e2635 Reviewed-on: https://go-review.googlesource.com/c/go/+/351460 Trust: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-08-04[dev.typeparams] runtime: handle d.link carefully when freeing a deferAustin Clements
CL 339396 allowed stack copying on entry to and during freedefer, but this introduced a subtle bug: if d is heap-allocated, and d.link points to a stack-allocated defer, stack copying during freedefer can briefly introduce a stale pointer, which the garbage collector can discover and panic about. This happens because d has already been unlinked from the defer chain when freedefer is called, so stack copying won't update stack pointers in it. Fix this by making freedefer nosplit again and immediately clearing d.link. This should fix the longtest builders, which currently fail on GOMAXPROCS=2 runtime -cpu=1,2,4 -quick in the TestDeferHeapAndStack test. This seems like the simplest fix, but it just deals with the subtlety rather than eliminating it. Really, every call site of freedefer (of which there are surprisingly many) has hidden subtlety between unlinking the defer and calling freedefer. We could consolidate the subtlety into each call site by requiring that they unlink the defer and set d.link to nil before calling freedefer. freedefer could check this condition like it checks that various other fields have already been zeroed. A more radical option is to replace freedefer with "popDefer", which would both pop the defer off the link and take care of freeing it. There would still be a brief moment of subtlety, but it would be in one place, in popDefer. Annoyingly, *almost* every call to freedefer just pops the defer from the head of the G's list, but there's one place when handling open-coded defers where we have to remove a defer from the middle of the list. I'm inclined to first fix that subtlety by only expanding open-coded defer records when they're at the head of the defer list, and then revisit the popDefer idea. Change-Id: I3130d2542c01a421a5d60e8c31f5379263219627 Reviewed-on: https://go-review.googlesource.com/c/go/+/339730 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-08-03[dev.typeparams] runtime: simplify freedeferAustin Clements
Currently, freedefer manually zeros all the fields in the _defer because simply assigning _defer{} used to cause a nosplit stack overflow. freedefer is no longer nosplit, so go back to the simpler, more robust code. Change-Id: I881f557bab3b1ee7ab29b68e7fb56d0fe6d35d8d Reviewed-on: https://go-review.googlesource.com/c/go/+/339669 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-08-03[dev.typeparams] runtime,cmd/compile,cmd/link: replace jmpdefer with a loopAustin Clements
Currently, deferreturn runs deferred functions by backing up its return PC to the deferreturn call, and then effectively tail-calling the deferred function (via jmpdefer). The effect of this is that the deferred function appears to be called directly from the deferee, and when it returns, the deferee calls deferreturn again so it can run the next deferred function if necessary. This unusual flow control leads to a large number of special cases and complications all over the tool chain. This used to be necessary because deferreturn copied the deferred function's argument frame directly into its caller's frame and then had to invoke that call as if it had been called from its caller's frame so it could access it arguments. But now that we've simplified defer processing so the runtime only deals with argument-less closures, this approach is no longer necessary. This CL simplifies all of this by making deferreturn simply call deferred functions in a loop. This eliminates the need for jmpdefer, so we can delete a bunch of per-architecture assembly code. This eliminates several special cases on Wasm, since it couldn't support these calling shenanigans directly and thus had to simulate the loop a different way. Now Wasm can largely work the way the other platforms do. This eliminates the per-architecture Ginsnopdefer operation. On PPC64, this was necessary to reload the TOC pointer after the tail call (since TOC pointers in general make tail calls impossible). The tail call is gone, and in the case where we do force a jump to the deferreturn call when recovering from an open-coded defer, we go through gogo (via runtime.recovery), which handles the TOC. On other platforms, we needed a NOP so traceback didn't get confused by seeing the return to the CALL instruction, rather than the usual return to the instruction following the CALL instruction. Now we don't inject a return to the CALL instruction at all, so this NOP is also unnecessary. The one potential effect of this is that deferreturn could now appear in stack traces from deferred functions. However, this could already happen from open-coded defers, so we've long since marked deferreturn as a "wrapper" so it gets elided not only from printed stack traces, but from runtime.Callers*. This is a retry of CL 337652 because we had to back out its parent. There are no changes in this version. Change-Id: I3f54b7fec1d7ccac71cc6cf6835c6a46b7e5fb6c Reviewed-on: https://go-review.googlesource.com/c/go/+/339397 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-08-03[dev.typeparams] runtime: remove unnecessary split-prevention from defer codeAustin Clements
Prior to regabi, the compiler passed defer arguments to the runtime as untyped values on the stack. This meant a lot of defer-related runtime functions had to be very careful not to grow the stack or allow preemption since the stack could not be safely scanned or moved. However, with regabi, every defer is now simply a func() from the runtime's perspective, which means we no longer have untyped values on the stack when we enter defer-related runtime code. Hence, this CL removes a lot of the now-unnecessary carefulness in the defer implementation. Specifically, deferreturn no longer needs to be nosplit because it doesn't copy untyped defer arguments to its caller's frame (we also update some stale comments in deferreturn). freedefer no longer needs to be nosplit because it's none of its callers are deeply nosplit. And newdefer and freedefer no longer need to switch to the systemstack on their slow paths to avoid stack growth. deferprocStack is the only function that still needs to be nosplit, but that's because the compiler calls it with uninitialized live pointer slots on the stack (maybe we should change that, but that's a very different fix). This is a retry of CL 337651, which was rolled back. This version disables preemption in newdefer and freedefer while they hold the current P. Change-Id: Ibf469addc0b69dc3ba9a3d1a5e0c2804b7b4b244 Reviewed-on: https://go-review.googlesource.com/c/go/+/339396 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-07-30[dev.typeparams] Revert "[dev.typeparams] runtime: remove unnecessary ↵Austin Clements
split-prevention from defer code" This reverts CL 337651. This causes `go test -count 1000 -run TestDeferHeapAndStack runtime` to fail with a SIGSEGV freedefer [https://build.golang.org/log/c113b366cc6d51146db02a07b4d7dd931133efd5] and possibly sometimes a GC bad pointer panic [https://build.golang.org/log/5b1cef7a9ad68704e9ef3ce3ad2fefca3ba86998]. Change-Id: Ie56c274b78603c81191213b302225ae19de27fb9 Reviewed-on: https://go-review.googlesource.com/c/go/+/338710 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-07-30[dev.typeparams] Revert "[dev.typeparams] runtime,cmd/compile,cmd/link: ↵Austin Clements
replace jmpdefer with a loop" This reverts CL 227652. I'm reverting CL 337651 and this builds on top of it. Change-Id: I03ce363be44c2a3defff2e43e7b1aad83386820d Reviewed-on: https://go-review.googlesource.com/c/go/+/338709 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-07-30[dev.typeparams] runtime,cmd/compile,cmd/link: replace jmpdefer with a loopAustin Clements
Currently, deferreturn runs deferred functions by backing up its return PC to the deferreturn call, and then effectively tail-calling the deferred function (via jmpdefer). The effect of this is that the deferred function appears to be called directly from the deferee, and when it returns, the deferee calls deferreturn again so it can run the next deferred function if necessary. This unusual flow control leads to a large number of special cases and complications all over the tool chain. This used to be necessary because deferreturn copied the deferred function's argument frame directly into its caller's frame and then had to invoke that call as if it had been called from its caller's frame so it could access it arguments. But now that we've simplified defer processing so the runtime only deals with argument-less closures, this approach is no longer necessary. This CL simplifies all of this by making deferreturn simply call deferred functions in a loop. This eliminates the need for jmpdefer, so we can delete a bunch of per-architecture assembly code. This eliminates several special cases on Wasm, since it couldn't support these calling shenanigans directly and thus had to simulate the loop a different way. Now Wasm can largely work the way the other platforms do. This eliminates the per-architecture Ginsnopdefer operation. On PPC64, this was necessary to reload the TOC pointer after the tail call (since TOC pointers in general make tail calls impossible). The tail call is gone, and in the case where we do force a jump to the deferreturn call when recovering from an open-coded defer, we go through gogo (via runtime.recovery), which handles the TOC. On other platforms, we needed a NOP so traceback didn't get confused by seeing the return to the CALL instruction, rather than the usual return to the instruction following the CALL instruction. Now we don't inject a return to the CALL instruction at all, so this NOP is also unnecessary. The one potential effect of this is that deferreturn could now appear in stack traces from deferred functions. However, this could already happen from open-coded defers, so we've long since marked deferreturn as a "wrapper" so it gets elided not only from printed stack traces, but from runtime.Callers*. Change-Id: Ie9f700cd3fb774f498c9edce363772a868407bf7 Reviewed-on: https://go-review.googlesource.com/c/go/+/337652 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-07-30[dev.typeparams] runtime: remove unnecessary split-prevention from defer codeAustin Clements
Prior to regabi, the compiler passed defer arguments to the runtime as untyped values on the stack. This meant a lot of defer-related runtime functions had to be very careful not to grow the stack or allow preemption since the stack could not be safely scanned or moved. However, with regabi, every defer is now simply a func() from the runtime's perspective, which means we no longer have untyped values on the stack when we enter defer-related runtime code. Hence, this CL removes a lot of the now-unnecessary carefulness in the defer implementation. Specifically, deferreturn no longer needs to be nosplit because it doesn't copy untyped defer arguments to its caller's frame (we also update some stale comments in deferreturn). freedefer no longer needs to be nosplit because it's none of its callers are deeply nosplit. And newdefer and freedefer no longer need to switch to the systemstack on their slow paths to avoid stack growth. deferprocStack is the only function that still needs to be nosplit, but that's because the compiler calls it with uninitialized live pointer slots on the stack (maybe we should change that, but that's a very different fix). Change-Id: I1156ec90bff2613fe4b48b84b375943349ce637d Reviewed-on: https://go-review.googlesource.com/c/go/+/337651 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-07-30[dev.typeparams] runtime: use func() for deferred functionsAustin Clements
Prior to regabi, a deferred function could have any signature, so the runtime always manipulated them as funcvals. Now, a deferred function is always func(). Hence, this CL makes the runtime's manipulation of deferred functions more type-safe by using func() directly instead of *funcval. Change-Id: Ib55f38ed49107f74149725c65044e4690761971d Reviewed-on: https://go-review.googlesource.com/c/go/+/337650 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-07-27[dev.typeparams] runtime: don't keep stack uintptr across potential stack moveAustin Clements
Currently, deferproc stores the caller SP as a uintptr in a local variable across a call to newdefer, but newdefer could grow the stack and invalidate this saved SP, causing deferproc to store a stale SP in the defer record. This would lead to us later failing to match that defer to its calling frame, and we wouldn't run the defer at the right time (or possibly at all). It turns out this isn't crashing horribly right now only because the compiler happens to only materialize the result of getcallersp when this variable is used, *after* the call to newdefer. But this is clearly on thin ice, so this CL moves the getcallersp() to the place where we actually need the result. Change-Id: Iae8ab226e03e4482f16acfb965885f0bd83a13b0 Reviewed-on: https://go-review.googlesource.com/c/go/+/337649 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-06-17[dev.typeparams] runtime: replace Goarch* constants with internal/goarch ↵Michael Anthony Knyszek
versions [generated] [git-generate] cd src/runtime gofmt -w -r "sys.Goarch386 -> goarch.Is386" . gofmt -w -r "sys.GoarchAmd64 -> goarch.IsAmd64" . gofmt -w -r "sys.GoarchAmd64p32 -> goarch.IsAmd64p32" . gofmt -w -r "sys.GoarchArm -> goarch.IsArm" . gofmt -w -r "sys.GoarchArmbe -> goarch.IsArmbe" . gofmt -w -r "sys.GoarchArm64 -> goarch.IsArm64" . gofmt -w -r "sys.GoarchArm64be -> goarch.IsArm64be" . gofmt -w -r "sys.GoarchPpc64 -> goarch.IsPpc64" . gofmt -w -r "sys.GoarchPpc64le -> goarch.IsPpc64le" . gofmt -w -r "sys.GoarchMips -> goarch.IsMips" . gofmt -w -r "sys.GoarchMipsle -> goarch.IsMipsle" . gofmt -w -r "sys.GoarchMips64 -> goarch.IsMips64" . gofmt -w -r "sys.GoarchMips64le -> goarch.IsMips64le" . gofmt -w -r "sys.GoarchMips64p32 -> goarch.IsMips64p32" . gofmt -w -r "sys.GoarchMips64p32le -> goarch.IsMips64p32le" . gofmt -w -r "sys.GoarchPpc -> goarch.IsPpc" . gofmt -w -r "sys.GoarchRiscv -> goarch.IsRiscv" . gofmt -w -r "sys.GoarchRiscv64 -> goarch.IsRiscv64" . gofmt -w -r "sys.GoarchS390 -> goarch.IsS390" . gofmt -w -r "sys.GoarchS390x -> goarch.IsS390x" . gofmt -w -r "sys.GoarchSparc -> goarch.IsSparc" . gofmt -w -r "sys.GoarchSparc64 -> goarch.IsSparc64" . gofmt -w -r "sys.GoarchWasm -> goarch.IsWasm" . goimports -w *.go Change-Id: I9d88e1284efabaeb0ee3733cba6286247d078c85 Reviewed-on: https://go-review.googlesource.com/c/go/+/328345 Trust: Michael Knyszek <mknyszek@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2021-06-16[dev.typeparams] Revert "[dev.typeparams] runtime: make deferproc take a ↵Cherry Mui
func() argument" Temprary revert CL 325918. Delve relies on the _defer.fn.fn field to get defer frames. CL 325918 changes the type of _defer.fn to func(), which no longer has an fn field. Change-Id: If6c71b15a27bac579593f5273c9a49715e6e35b2 Reviewed-on: https://go-review.googlesource.com/c/go/+/327775 Trust: Cherry Mui <cherryyz@google.com> Trust: Dan Scales <danscales@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
2021-06-11[dev.typeparams] runtime: simplify defer record allocationCherry Mui
Now that deferred functions are always argumentless and defer records are no longer with arguments, defer record can be fixed size (just the _defer struct). This allows us to simplify the allocation of defer records, specifically, remove the defer classes and the pools of different sized defers. Change-Id: Icc4b16afc23b38262ca9dd1f7369ad40874cf701 Reviewed-on: https://go-review.googlesource.com/c/go/+/326062 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org>
2021-06-09[dev.typeparams] cmd/compile, runtime: simplify opendefer metadataCherry Mui
Now that deferred functions are always argumentless, we don't need the metadata for the frame size, number of arguments, and the information about each argument. Change-Id: I99e75248a22bda6efbdf2012a2f35beca4c18fd7 Reviewed-on: https://go-review.googlesource.com/c/go/+/326061 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
2021-06-08[dev.typeparams] cmd/compile, runtime: remove _defer.siz fieldCherry Mui
As deferred function now always has zero arguments, _defer.siz is always 0 and can be removed. Change-Id: Ibb89f65b2f9d2ba4aeabe50438cc3d4b6a88320b Reviewed-on: https://go-review.googlesource.com/c/go/+/325921 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-06-08[dev.typeparams] runtime: allow deferproc split stackCherry Mui
deferproc was not allowed to split stack because it had a special stack layout, where the go'd function's arguments were passed on stack but not included in the signature (therefore the stack map). Now it no longer has argument, so it does not need to be nosplit. Change-Id: I6d4b5302bd6fea6642bb4202984d86e3ebbc9054 Reviewed-on: https://go-review.googlesource.com/c/go/+/325920 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-06-08[dev.typeparams] runtime: make deferproc take a func() argumentCherry Mui
Previously it takes a *funcval, as it can be any function types. Now it must be func(). Make it so. Change-Id: I04273047b024386f55dbbd5fbda4767cbee7ac93 Reviewed-on: https://go-review.googlesource.com/c/go/+/325918 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-06-08[dev.typeparams] cmd/compile, runtime: remove the siz argument of ↵Cherry Mui
newproc/deferproc newproc/deferproc takes a siz argument for the go'd/deferred function's argument size. Now it is always zero. Remove the argument. Change-Id: If1bb8d427e34015ccec0ba10dbccaae96757fa8c Reviewed-on: https://go-review.googlesource.com/c/go/+/325917 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-06-08[dev.typeparams] runtime: remove variadic defer/go callsCherry Mui
Now that defer/go wrapping is used, deferred/go'd functions are always argumentless. Remove the code handling arguments. This CL is mostly removing the fallback code path. There are more cleanups to be done, in later CLs. Change-Id: I87bfd3fb2d759fbeb6487b8125c0f6992863d6e5 Reviewed-on: https://go-review.googlesource.com/c/go/+/325915 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-06-08[dev.typeparams] cmd/compile, runtime: always enable defer/go wrappingCherry Mui
Hardwire regabidefers to true. Remove it from GOEXPERIMENTs. Fallback paths are not cleaned up in this CL. That will be done in later CLs. Change-Id: Iec1112a1e55d5f6ef70232a5ff6e702f649071c4 Reviewed-on: https://go-review.googlesource.com/c/go/+/325913 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
2021-04-21cmd/compile: allow conversion from slice to array ptrJosh Bleecher Snyder
Panic if the slice is too short. Updates #395 Change-Id: I90f4bff2da5d8f3148ba06d2482084f32b25c29a Reviewed-on: https://go-review.googlesource.com/c/go/+/301650 Trust: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2021-04-12runtime: remove deferreturn dummy argumentCherry Zhang
deferreturn has a dummy argument, that is only used for getting the caller's SP. When generating deferreturn calls, the compiler does not pass an actual argument or reserve its stack space. Also, the current code is written with the assumption about where the argument's address is on the stack. Currently this is correct for both ABI0 and the register ABI, but it may change in the future (e.g. if we remove dedicated spill slots). Remove the argument. Also remove the argument for getargp. Change-Id: I96d07efa79a9c1a53ef3fc5adbecc11877e99dc1 Reviewed-on: https://go-review.googlesource.com/c/go/+/309329 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
2021-04-08internal/goexperiment: consolidate experiment-enabled constantsAustin Clements
Currently, we have boolean and integral constants for GOEXPERIMENTs in various places. Consolidate these into automatically generated constants in the internal/goexperiment package. Change-Id: I42a49aba2a3b4c722fedea23a613162cd8a67bee Reviewed-on: https://go-review.googlesource.com/c/go/+/307818 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2021-04-06runtime: use funcID to identify abort in isAbortPCMichael Anthony Knyszek
This change eliminates the use of funcPC to determine if an PC is in abort. Using funcPC for this purpose is problematic when using plugins because symbols no longer have unique PCs. funcPC also grabs the wrapper for runtime.abort which isn't what we want for the new register ABI, so rather than mark runtime.abort as ABIInternal, use funcID. For #40724. Change-Id: I2730e99fe6f326d22d64a10384828b94f04d101a Reviewed-on: https://go-review.googlesource.com/c/go/+/307391 Trust: Michael Knyszek <mknyszek@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Austin Clements <austin@google.com>
2021-03-31runtime: replace reflectcall of defers with direct callAustin Clements
With GOEXPERIMENT=regabidefer, all deferred functions take no arguments and have no results (their signature is always func()). Since the signature is fixed, we can replace all of the reflectcalls in the defer code with direct closure calls. For #40724. Change-Id: I3acd6742fe665610608a004c675f473b9d0e65ee Reviewed-on: https://go-review.googlesource.com/c/go/+/306010 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
2021-03-30runtime: check that defer/go frames are emptyAustin Clements
With GOEXPERIMENT=regabidefer, these frames should always be empty. Check that. For #40724. Change-Id: Id8e418a9e06b4f94543cb16b868a7e10e013c2d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/306009 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
2021-03-13all: remove duplicate wordsJohn Bampton
Change-Id: Ib0469232a2b69a869e58d5d24990ad74ac96ea56 GitHub-Last-Rev: eb38e049ee1e773392ff3747e1eb2af20dd50dcd GitHub-Pull-Request: golang/go#44805 Reviewed-on: https://go-review.googlesource.com/c/go/+/299109 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
2021-02-16[dev.regabi] reflect: support for register ABI on amd64 for reflect.(Value).CallMichael Anthony Knyszek
This change adds support for the new register ABI on amd64 to reflect.(Value).Call. If internal/abi's register counts are non-zero, reflect will try to set up arguments in registers on the Call path. Note that because the register ABI becomes ABI0 with zero registers available, this should keep working as it did before. This change does not add any tests for the register ABI case because there's no way to do so at the moment. For #40724. Change-Id: I8aa089a5aa5a31b72e56b3d9388dd3f82203985b Reviewed-on: https://go-review.googlesource.com/c/go/+/272568 Trust: Michael Knyszek <mknyszek@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
2021-01-27runtime: make sure to remove open-coded defer entries in all cases after a ↵Dan Scales
recover We add entries to the defer list at panic/goexit time on-the-fly for frames with open-coded defers. We do this so that we can correctly process open-coded defers and non-open-coded defers in the correct order during panics/goexits. But we need to remove entries for open-coded defers from the defer list when there is a recover, since those entries may never get removed otherwise and will get stale, since their corresponding defers may now be processed normally (inline). This bug here is that we were only removing higher-up stale entries during a recover if all defers in the current frame were done. But we could have more defers in the current frame (as the new test case shows). In this case, we need to leave the current defer entry around for use by deferreturn, but still remove any stale entries further along the chain. For bug 43921, simple change that we should abort the removal loop for any defer entry that is started (i.e. in process by a still not-recovered outer panic), even if it is not an open-coded defer. This change does not fix bug 43920, which looks to be a more complex fix. Fixes #43882 Fixes #43921 Change-Id: Ie05b2fa26973aa26b25c8899a2abc916090ee4f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/286712 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com>