Compare commits

...

33 Commits

Author SHA1 Message Date
Carlos Amedee
564c76a268 [release-branch.go1.14] go1.14.1
Change-Id: I3399052efb62529d32bb0866fd324d802beb6e4c
Reviewed-on: https://go-review.googlesource.com/c/go/+/223923
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alexander Rakoczy <alex@golang.org>
2020-03-19 15:17:01 +00:00
Ian Lance Taylor
b620f6fde5 [release-branch.go1.14] doc/go1.14: mention Windows change for Open permissions
For #35033
For #36878

Change-Id: Ie15353322d5cfe7320199103ad9543fb89a842ed
Reviewed-on: https://go-review.googlesource.com/c/go/+/223957
Reviewed-by: Brendan Jackman <jackmanb@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit e39de05186)
Reviewed-on: https://go-review.googlesource.com/c/go/+/223962
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2020-03-18 20:51:21 +00:00
Cherry Zhang
e577ba98d8 [release-branch.go1.14] runtime: don't send preemption signal if there is a signal pending
If multiple threads call preemptone to preempt the same M, it may
send many signals to the same M such that it hardly make
progress, causing live-lock problem. Only send a signal if there
isn't already one pending.

Updates #37741.
Fixes #37833.

Change-Id: Id94adb0b95acbd18b23abe637a8dcd81ab41b452
Reviewed-on: https://go-review.googlesource.com/c/go/+/223737
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit 0c0e8f224d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/223939
Reviewed-by: Austin Clements <austin@google.com>
2020-03-18 18:38:30 +00:00
Keith Randall
229247d33b [release-branch.go1.14] runtime: don't report a pointer alignment error for pointer-free base type
Fixes #37905

Change-Id: I8ba9c8b106e16cea7dd25473c7390b0f2ba9a1a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/223781
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/223749
2020-03-18 16:19:45 +00:00
Ian Lance Taylor
c5125098b2 [release-branch.go1.14] runtime: don't crash on mlock failure
Instead, note that mlock has failed, start trying the mitigation of
touching the signal stack before sending a preemption signal, and,
if the program crashes, mention the possible problem and a wiki page
describing the issue (https://golang.org/wiki/LinuxKernelSignalVectorBug).

Tested on a kernel in the buggy version range, but with the patch,
by using `ulimit -l 0`.

For #37436
Fixes #37807

Change-Id: I072aadb2101496dffd655e442fa5c367dad46ce8
Reviewed-on: https://go-review.googlesource.com/c/go/+/223121
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit b851e51160)
Reviewed-on: https://go-review.googlesource.com/c/go/+/223417
TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-03-16 19:55:30 +00:00
Bryan C. Mills
adba22a9ae [release-branch.go1.14] cmd/go: include the go language version in cache keys
Fixes #37822
Updates #37804

Change-Id: I4381dc5c58cfd467506d3d73fbd19c2c7257338e
Reviewed-on: https://go-review.googlesource.com/c/go/+/223139
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
(cherry picked from commit feea3f165770025b045c6dd46747b1debdaf348e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/223141
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2020-03-12 15:38:41 +00:00
Dan Scales
fd85ff5ee0 [release-branch.go1.14] runtime: fix problem with repeated panic/recover/re-panics and open-coded defers
In the open-code defer implementation, we add defer struct entries to the defer
chain on-the-fly at panic time to represent stack frames that contain open-coded
defers. This allows us to process non-open-coded and open-coded defers in the
correct order. Also, we need somewhere to be able to store the 'started' state of
open-coded defers. However, if a recover succeeds, defers will now be processed
inline again (unless another panic happens). Any defer entry representing a frame
with open-coded defers will become stale once we run the corresponding defers
inline and exit the associated stack frame. So, we need to remove all entries for
open-coded defers at recover time.

The current code was only removing the top-most open-coded defer from the defer
chain during recovery. However, with recursive functions that do repeated
panic-recover-repanic, multiple stale entries can accumulate on the chain. So, we
just adjust the loop to process the entire chain. Since this is at panic/recover
case, it is fine to scan through the entire chain (which should usually have few
elements in it, since most defers are open-coded).

The added test fails with a SEGV without the fix, because it tries to run a stale
open-code defer entry (and the stack has changed).

Updates #37664.
Fixes #37782.

Change-Id: I8e3da5d610b5e607411451b66881dea887f7484d
Reviewed-on: https://go-review.googlesource.com/c/go/+/222420
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit fae87a2223)
Reviewed-on: https://go-review.googlesource.com/c/go/+/222818
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2020-03-11 14:37:29 +00:00
Keith Randall
8e804f19b6 [release-branch.go1.14] runtime: make typehash match compiler generated hashes exactly
If typehash (used by reflect) does not match the built-in map's hash,
then problems occur. If a map is built using reflect, and then
assigned to a variable of map type, the hash function can change. That
causes very bad things.

This issue is rare. MapOf consults a cache of all types that occur in
the binary before making a new one. To make a true new map type (with
a hash function derived from typehash) that map type must not occur in
the binary anywhere. But to cause the bug, we need a variable of that
type in order to assign to it. The only way to make that work is to
use a named map type for the variable, so it is distinct from the
unnamed version that MapOf looks for.

Fixes #37721

Change-Id: I3537bfceca8cbfa1af84202f432f3c06953fe0ed
Reviewed-on: https://go-review.googlesource.com/c/go/+/222357
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
(cherry picked from commit 2b8e60d464)
Reviewed-on: https://go-review.googlesource.com/c/go/+/222778
2020-03-10 20:06:03 +00:00
Keith Randall
6717d27be2 [release-branch.go1.14] runtime: special case interface hashing for pointers
Interfaces often contain pointers. Implement a fast path for this case.

name                   old time/op  new time/op  delta
MapInterfaceString-16  21.4ns ±19%  20.5ns ±10%     ~     (p=0.361 n=10+10)
MapInterfacePtr-16     25.8ns ± 8%  17.3ns ± 7%  -33.11%  (p=0.000 n=10+9)

We need this CL as well to fix 37721.
Update #37721
Fixes #37613

Change-Id: Ice52820e6259a3edeafcbbbeb25b1e363bef00d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/219338
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
(cherry picked from commit afd691c579)
Reviewed-on: https://go-review.googlesource.com/c/go/+/222779
Run-TryBot: Alexander Rakoczy <alex@golang.org>
2020-03-10 20:05:44 +00:00
Michael Pratt
9c41c1d8dc [release-branch.go1.14] runtime/pprof: expand final stack frame to avoid truncation
When generating stacks, the runtime automatically expands inline
functions to inline all inline frames in the stack. However, due to the
stack size limit, the final frame may be truncated in the middle of
several inline frames at the same location.

As-is, we assume that the final frame is a normal function, and emit and
cache a Location for it. If we later receive a complete stack frame, we
will first use the cached Location for the inlined function and then
generate a new Location for the "caller" frame, in violation of the
pprof requirement to merge inlined functions into the same Location.

As a result, we:

1. Nondeterministically may generate a profile with the different stacks
combined or split, depending on which is encountered first. This is
particularly problematic when performing a diff of profiles.

2. When split stacks are generated, we lose the inlining information.

We avoid both of these problems by performing a second expansion of the
last stack frame to recover additional inline frames that may have been
lost. This expansion is a bit simpler than the one done by the runtime
because we don't have to handle skipping, and we know that the last
emitted frame is not an elided wrapper, since it by definition is
already included in the stack.

Fixes #37447

Change-Id: If3ca2af25b21d252cf457cc867dd932f107d4c61
Reviewed-on: https://go-review.googlesource.com/c/go/+/221577
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
(cherry picked from commit fadbf7404d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/222762
2020-03-10 19:03:26 +00:00
Cherry Zhang
2e08d80732 [release-branch.go1.14] runtime: don't save/restore FP registers in softfloat mode on MIPS(64)
Fixes #37667.
Updates #37653.

Change-Id: I6188e44b4bc4aba7b56f29d9ce9de4618c70fd7b
Reviewed-on: https://go-review.googlesource.com/c/go/+/222057
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
(cherry picked from commit 588ee7987d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/222062
2020-03-10 19:00:12 +00:00
Jay Conrod
76a6adcf3a [release-branch.go1.14] cmd/go: make go test -json report failures for panicking/exiting tests
'go test -json' should report that a test failed if the test binary
did not exit normally with status 0. This covers panics, non-zero
exits, and abnormal terminations.

These tests don't print a final result when run with -test.v (which is
used by 'go test -json'). The final result should be "PASS" or "FAIL"
on a line by itself. 'go test' prints "FAIL" in this case, but
includes error information.

test2json was changed in CL 192104 to report that a test passed if it
does not report a final status. This caused 'go test -json' to report
that a test passed after a panic or non-zero exit.

With this change, test2json treats "FAIL" with error information the
same as "FAIL" on a line by itself. This is intended to be a minimal
fix for backporting, but it will likely be replaced by a complete
solution for #29062.

Fixes #37671
Updates #37555
Updates #29062
Updates #31969

Change-Id: Icb67bcd36bed97e6a8d51f4d14bf71f73c83ac3d
Reviewed-on: https://go-review.googlesource.com/c/go/+/222243
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit 5ea58c6346)
Reviewed-on: https://go-review.googlesource.com/c/go/+/222658
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
2020-03-09 17:20:31 +00:00
Stefan Baebler
0e9f7ac7ca [release-branch.go1.14] doc/go1.14: document that unparsable URL in net/url.Error is now quoted
Updates #37614
Updates #36878
Updates #29384
Fixes #37630

Change-Id: I63dad8b554353197ae0f29fa2a84f17bffa58557
GitHub-Last-Rev: 5297df3220
GitHub-Pull-Request: golang/go#37661
Reviewed-on: https://go-review.googlesource.com/c/go/+/222037
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 2b0f481278)
Reviewed-on: https://go-review.googlesource.com/c/go/+/222317
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2020-03-06 18:42:56 +00:00
Hana (Hyang-Ah) Kim
e6036e7da5 [release-branch.go1.14] cmd/trace: update to use WebComponents V0 polyfill
Old trace viewer stopped working with Chrome M80+ because the
old trace viewer heavily depended on WebComponents V0 which are deprecated.
Trace viewer recently migrated to use WebComponents V0 polyfill
(crbug.com/1036492). This CL brings in the newly updated trace_viewer_full.html
(sync'd @ 9508452e)
and updates the javascript snippet included in the /trace endpoint
to use the polyfill.

This brings in webcomponents.min.js copied from
https://chromium.googlesource.com/catapult/+/9508452e18f130c98499cb4c4f1e1efaedee8962/third_party/polymer/components/webcomponentsjs/webcomponents.min.js

That is necessary because the /trace endpoint needs to import
the vulcanized trace_viewer_full.html.

It's possible that some features are not working correctly with
this polyfill. In that case, report the issue to crbug.com/1036492.
There will be a warning message in the UI (yellow banner above the timeline)
which can be hidden by clicking the 'hide' button.

This allows to render the trace in browsers other than chrome in theory,
but I observed some buttons and functions still don't work outside
chrome.

Updates #34374.
Fixes #37343.

Change-Id: I0f369b15349dd0f4718c261ec23dfab6a47ace2f
Reviewed-on: https://go-review.googlesource.com/c/go/+/219997
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
(cherry picked from commit 75ea964b3f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/220323
2020-03-02 22:35:40 +00:00
Cherry Zhang
c54e36905b [release-branch.go1.14] runtime: guard VZEROUPPER on CPU feature
In CL 219131 we inserted a VZEROUPPER instruction on darwin/amd64.
The instruction is not available on pre-AVX machines. Guard it
with CPU feature.

Updates #37459.
Fixes #37478.

Change-Id: I9a064df277d091be4ee594eda5c7fd8ee323102b
Reviewed-on: https://go-review.googlesource.com/c/go/+/221057
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit c46ffdd2ec)
Reviewed-on: https://go-review.googlesource.com/c/go/+/221058
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2020-03-02 22:30:16 +00:00
Ian Lance Taylor
329317472f [release-branch.go1.14] runtime: don't panic on racy use of timers
If we see a racy use of timers, as in concurrent calls to Timer.Reset,
do the operations in an unpredictable order, rather than crashing.

Updates #37400
Updates #37449
Fixes #37494

Change-Id: Idbac295df2dfd551b6d762909d5040fc532c1b34
Reviewed-on: https://go-review.googlesource.com/c/go/+/221077
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 98858c4380)
Reviewed-on: https://go-review.googlesource.com/c/go/+/221298
2020-02-27 23:15:33 +00:00
Kevin Burke
99f8de7339 [release-branch.go1.14] doc/articles/race_detector: mention memory leak potential
As far as I can tell, there is no public documentation on this topic,
which cost me several days of debugging.

I am possibly unusual in that I run binaries in production with the
race detector turned on, but I think that others who do the same may
want to be aware of the risk.

Updates #26813.
Updates #37233.

Change-Id: I1f8111bd01d0000596e6057b7cb5ed017d5dc655
Reviewed-on: https://go-review.googlesource.com/c/go/+/220586
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
(cherry picked from commit ba093c4562)
Reviewed-on: https://go-review.googlesource.com/c/go/+/221019
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-02-25 23:52:57 +00:00
Alexander Rakoczy
3dcb516d42 [release-branch.go1.14] doc/go1.14: add link to module migration guide
Adding a link to this guide will provide more value to instructing Go
users to migrate to modules.

Updates #36878

Change-Id: Ie6ab45efcd35cc5e5ba5adc16ba0ca4cca4292bc
Reviewed-on: https://go-review.googlesource.com/c/go/+/220906
Run-TryBot: Alexander Rakoczy <alex@golang.org>
Reviewed-by: thepudds <thepudds1460@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
(cherry picked from commit 8e2dad5529)
Reviewed-on: https://go-review.googlesource.com/c/go/+/220981
Reviewed-by: Carlos Amedee <carlos@golang.org>
2020-02-25 21:16:09 +00:00
Carlos Amedee
20a838ab94 [release-branch.go1.14] go1.14
Change-Id: Ic949a6caa8d55115630d0e8e7c9480b54c987b31
Reviewed-on: https://go-review.googlesource.com/c/go/+/220901
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2020-02-25 17:40:40 +00:00
Carlos Amedee
c49910abc3 [release-branch.go1.14] doc: add Go 1.14 to release history
Change-Id: I02afbd08ce9e0cd2af8953693b9c3066f6465914
Reviewed-on: https://go-review.googlesource.com/c/go/+/220937
Reviewed-by: Carlos Amedee <carlos@golang.org>
2020-02-25 16:17:11 +00:00
Tobias Klauser
6a7f08952e [release-branch.go1.14] doc/go1.14: document that freebsd/arm64 requires FreeBSD 12.0 or later
Updates #24715
Updates #37345

Change-Id: I787a9b2ab1c68e1d379aac0a31bdf6217f04f911
Reviewed-on: https://go-review.googlesource.com/c/go/+/220426
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
(cherry picked from commit 28c501b7b3)
Reviewed-on: https://go-review.googlesource.com/c/go/+/220427
2020-02-24 21:19:38 +00:00
Dmitri Shuralyov
8ced42e78b [release-branch.go1.14] doc/go1.14: remove draft notice
Use consistent indentation for one of the paragraphs.

Include issue number in the visible text, so it is easier to read.

Updates #36878

Change-Id: Iab857b26b1d27b0137e981126207089db108d530
Reviewed-on: https://go-review.googlesource.com/c/go/+/220646
Reviewed-by: Alexander Rakoczy <alex@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
(cherry picked from commit 1c0d664128)
Reviewed-on: https://go-review.googlesource.com/c/go/+/220650
2020-02-24 20:08:25 +00:00
Katie Hockman
f63e55b541 [release-branch.go1.14] crypto/cipher: require non-zero nonce size for AES-GCM
Also fix typo in crypto/cipher/gcm_test.go.

Updates #37118
Fixes #37416

Change-Id: I8544d1eeeb1f0336cebb977b8c5bfa5e4c5ad8c7
Reviewed-on: https://go-review.googlesource.com/c/go/+/218500
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
(cherry picked from commit 4e8badbbc2)
Reviewed-on: https://go-review.googlesource.com/c/go/+/220651
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Alexander Rakoczy <alex@golang.org>
2020-02-24 20:07:06 +00:00
vovapi
17acbdb357 [release-branch.go1.14] hash/maphash: don't discard data on random seed init
Hash initializes seed on the first usage of seed or state with initSeed.
initSeed uses SetSeed which discards accumulated data.
This causes hash to return different sums for the same data in the first use
and after reset.
This CL fixes this issue by separating the seed set from data discard.

Updates #37315

Change-Id: Ic7020702c2ce822eb700af462e37efab12f72054
GitHub-Last-Rev: 48b2f963e8
GitHub-Pull-Request: golang/go#37328
Reviewed-on: https://go-review.googlesource.com/c/go/+/220259
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit 638df87fa4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/220617
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2020-02-24 15:47:07 +00:00
Dmitri Shuralyov
babeec29aa [release-branch.go1.14] CONTRIBUTORS: second round of updates for Go 1.14
This update was automatically generated using the updatecontrib command:

	cd gotip
	go run golang.org/x/build/cmd/updatecontrib

With minor manual changes based on publicly available information
to canonicalize letter case and formatting for a few names.

Actions taken (relative to CONTRIBUTORS at origin/master):

	Added Aaron Bieber <deftly@gmail.com>
	Added Adam Williams <pwnfactory@gmail.com>
	Added Ayke van Laethem <aykevanlaethem@gmail.com>
	Added Bradford Lamson-Scribner <brad.lamson@gmail.com>
	Added Brian Falk <falk@logicparty.org>
	Added Chen Zhihan <energiehund@gmail.com>
	Added Christopher Loessl <cloessl+github@gmail.com>
	Added Frederik Zipp <fzipp@gmx.de>
	Added Fujimoto Kyosuke <kyoro.f@gmail.com>
	Added GitHub User jopbrown (6345470) <msshane2008@gmail.com>
	Added GitHub User yah01 (12216890) <kagaminehuan@gmail.com>
	Added Hiromichi Ema <ema.hiro@gmail.com>
	Added Jamal Carvalho <jamal.a.carvalho@gmail.com>
	Added Jason Baker <jason-baker@users.noreply.github.com>
	Added Kanta Ebihara <kantaebihara@gmail.com>
	Added Kirill Tatchihin <kirabsuir@gmail.com>
	Added Kévin Dunglas <dunglas@gmail.com>
	Added Mariano Cano <mariano@smallstep.com>
	Added Sergey Ivanov <ser1325@gmail.com>
	Added Thomas Symborski <thomas.symborski@gmail.com>
	Added Tomohiro Kusumoto <zabio1192@gmail.com>
	Added Xingqang Bai <bxq2011hust@qq.com>
	Used GitHub User jopbrown (6345470) form for jopbrown <msshane2008@gmail.com> https://github.com/golang/exp/commit/0405dc7 [exp]
	Used GitHub User yah01 (12216890) form for yah01 <kagaminehuan@gmail.com> https://github.com/golang/go/commit/ee55dd6b64 [go]
	Used GitHub name "Hiromichi Ema" for emahiro <ema.hiro@gmail.com> https://github.com/golang/tools/commit/b6336cbc [tools]
	Used GitHub name "Jamal Carvalho" for Gopher <jamal.a.carvalho@gmail.com> https://github.com/golang/gddo/commit/31dd61d [gddo]
	Used GitHub name "Xingqang Bai" for bxq2011hust <bxq2011hust@qq.com> https://github.com/golang/go/commit/79ccbe1b67 [go]

Updates #12042

Change-Id: I13f8ab37f8b38f8f5d0ff71c939ad39d0bc4f985
Reviewed-on: https://go-review.googlesource.com/c/go/+/220363
Reviewed-by: Alexander Rakoczy <alex@golang.org>
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/220368
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-02-21 21:25:53 +00:00
Daniel Martí
b4dca6416f [release-branch.go1.14] doc/go1.14: document the change to json.Number decoding
It might break a program if it was depending on undocumented behavior.
Give a proper heads up.

Updates #37308.

Change-Id: Id65bc70def1138d5506b694329c52250b417ec6f
Reviewed-on: https://go-review.googlesource.com/c/go/+/220418
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/220367
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-02-21 21:25:39 +00:00
Dmitri Shuralyov
f5293d77a9 [release-branch.go1.14] all: merge master into release-branch.go1.14
1cd724acb6 doc/go1.14: highlight the addition of hash/maphash package
a0cf2c872f doc/go1.14: remove TODO comment for CL 200439
a9ea91d571 cmd/link, runtime: skip holes in func table
88e564edb1 doc/go1.14: add missing period at sentence end
6917529cc6 testing: remove obsolete comment in testing.(*T) docs

Change-Id: Ifb581c251474e9445d65a4f34dd4dcbc469fdd79
2020-02-21 15:24:10 -05:00
Dmitri Shuralyov
51534757da [release-branch.go1.14] all: merge master into release-branch.go1.14
3eab754cd0 runtime: correct caller PC/SP offsets in walltime1/nanotime1
123f7dd3e1 runtime: zero upper bit of Y registers in asyncPreempt on darwin/amd64
a0c9fb6bd3 hash/maphash: mention the results are 64-bit integers
e237df5b53 runtime: fix fallback logic for aeshash on 32/64 bit
363bcd0068 cmd/go: eliminate empty '()' when passing -mod=readonly explicitly to 'go list'
7385947825 cmd/go/internal/modcmd: remove dead function addModFlag
5ce8005990 cmd/go/internal/web: fix a typo
d0050e2871 go/build: populate partial package information in importGo
1c241d2879 hash/maphash: mention that hash values do not persist in package docs
25da21ddc9 crypto/elliptic: document the Name and names of each curve
ab5d9f5831 doc/go1.14: add a couple minor crypto release notes
6a8164a254 go/doc: clarify that NewFromFiles caller must filter by GOOS/GOARCH
dff55c1f76 doc: move doc/modules.md to x/website
cfe2ab42e7 doc/go1.14: rearrange in alphabetical order
ca8bf63809 doc/go1.14: add link to TempFile in io/ioutil
a528215693 doc/go1.14: fix inconsistent markup
a6b03c64b2 runtime/race: update reference to compiler-rt sources
60d437f994 runtime: avoid double notewakeup in netpoll stub code
b8061825e5 doc: fill in 'go mod init' section of module documentation
cb16d26bd6 doc: fill in 'go mod download' section of module documentation
08d41dbb10 doc: fill in 'go list -m' section in module documentation
ff091b5fa0 doc: fill in 'Module-aware commands' section in module documentation
c7c525a79d doc: add section on module paths to module documentation
153a9e8033 doc: add section on go.mod file syntax
1a37095062 Revert "cmd/link: code cleanup in macho_combine_dwarf.go"
494dd1dddc cmd/link: code cleanup in macho_combine_dwarf.go

Change-Id: I9cd3edde698c3b87d2f3b3d9d6bdd5e6dae4e221
2020-02-13 14:59:50 -05:00
Carlos Amedee
d898c7b544 [release-branch.go1.14] all: merge master into release-branch.go1.14
ab7c174183 testing: make Cleanup work for benchmarks too.
ee3a3717aa doc/go1.14: disable text/template processing in HTML page
dd0aa799eb doc/go1.14: quote {{ and }} in text/template note
9ee51745f7 doc/go1.14: mention better error checking in text/template
e5b9c10689 doc/go1.14: document io/ioutil.TempDir's predictable prefix+suffix
7a36fa4002 crypto/x509: fix godoc for MarshalPKCS8PrivateKey
921ceadd29 runtime: rewrite a comment in malloc.go
88ae4ccefb math/big: reintroduce pre-Go 1.14 mention in GCD docs
60f11c44c0 doc/go1.14: document http.ServeFile large file fix for Windows
8a4d05cf07 cmd/go/internal/vet: only set work.VetExplicit if the list of explicit flags is non-empty
702226f933 doc/install.html: streamline the “Test your installation” step and make it module-agnostic
ffd4e32885 doc/go1.14: add remarks about range inference and check removal

Change-Id: Ie5f46d6f77fd792687f2aba0c1fa92cbe8a3a45b
2020-02-06 20:10:47 +00:00
Filippo Valsorda
29ccdfc853 [release-branch.go1.14] math/big: reintroduce pre-Go 1.14 mention in GCD docs
It was removed in CL 217302 but was intentionally added in CL 217104.

Change-Id: I1a478d80ad1ec4f0a0184bfebf8f1a5e352cfe8c
Reviewed-on: https://go-review.googlesource.com/c/go/+/217941
Reviewed-by: Robert Griesemer <gri@golang.org>
(cherry picked from commit 88ae4ccefb)
Reviewed-on: https://go-review.googlesource.com/c/go/+/217997
Reviewed-by: Katie Hockman <katie@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-02-05 23:01:27 +00:00
Katie Hockman
3f0cdedfdd [release-branch.go1.14] crypto/x509: fix godoc for MarshalPKCS8PrivateKey
Updates #36735
Fixes #37068

Change-Id: I93f005d78f4bfac773272995b165172461bae92f
Reviewed-on: https://go-review.googlesource.com/c/go/+/217917
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
(cherry picked from commit 7a36fa4002)
Reviewed-on: https://go-review.googlesource.com/c/go/+/217999
2020-02-05 22:18:49 +00:00
Carlos Amedee
a068054af1 [release-branch.go1.14] go1.14rc1
Change-Id: I6afa01a5240e1852a0081d8e1452b0b305652180
Reviewed-on: https://go-review.googlesource.com/c/go/+/217838
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2020-02-05 15:43:27 +00:00
Carlos Amedee
331b8661a0 [release-branch.go1.14] all: merge master into release-branch.go1.14
a864cc7560 doc: rename HTML element IDs to avoid duplicates
fb93cd45a6 net: don't check LookupHost error in TestLookupNullByte
f770366f6d runtime: don't treat SIGURG as a bad signal
e3f2e9ac4e internal/bytealg: fix riscv64 offset names

Change-Id: I2ef0665dce7f1ade9b6c826cfd5c8eab041ff23f
2020-02-05 09:44:03 -05:00
45 changed files with 2298 additions and 850 deletions

View File

@@ -26,6 +26,7 @@
Aamir Khan <syst3m.w0rm@gmail.com>
Aaron Beitch <aaronb@arista.com>
Aaron Bieber <deftly@gmail.com>
Aaron Cannon <cannona@fireantproductions.com>
Aaron France <aaron.l.france@gmail.com>
Aaron Jacobs <jacobsa@google.com>
@@ -48,6 +49,7 @@ Adam Shannon <adamkshannon@gmail.com>
Adam Shelton <aashelt90@gmail.com>
Adam Sindelar <adamsh@google.com>
Adam Thomason <athomason@gmail.com>
Adam Williams <pwnfactory@gmail.com>
Adam Woodbeck <adam@woodbeck.net>
Adarsh Ravichandran <adarshravichandran91@gmail.com>
Aditya Harindar <aditya.harindar@gmail.com>
@@ -276,6 +278,7 @@ Awn Umar <awn@cryptolosophy.io>
Axel Wagner <axel.wagner.hh@googlemail.com>
Ayan George <ayan@ayan.net>
Ayanamist Yang <ayanamist@gmail.com>
Ayke van Laethem <aykevanlaethem@gmail.com>
Aymerick Jéhanne <aymerick@jehanne.org>
Azat Kaumov <kaumov.a.r@gmail.com>
Baiju Muthukadan <baiju.m.mail@gmail.com>
@@ -338,6 +341,7 @@ Brad Jones <rbjones@google.com>
Brad Morgan <brad@morgabra.com>
Brad Whitaker <bwhitaker@fastly.com>
Braden Bassingthwaite <bbassingthwaite@vendasta.com>
Bradford Lamson-Scribner <brad.lamson@gmail.com>
Bradley Falzon <brad@teambrad.net>
Brady Catherman <brady@gmail.com>
Brady Sullivan <brady@bsull.com>
@@ -351,6 +355,7 @@ Brett Cannon <bcannon@gmail.com>
Brett Merrill <brett.j.merrill94@gmail.com>
Brian Dellisanti <briandellisanti@gmail.com>
Brian Downs <brian.downs@gmail.com>
Brian Falk <falk@logicparty.org>
Brian G. Merrell <bgmerrell@gmail.com>
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> <bgm@google.com>
Brian Kennedy <btkennedy@gmail.com>
@@ -404,6 +409,7 @@ Charles L. Dorian <cldorian@gmail.com>
Charles Lee <zombie.fml@gmail.com>
Charles Weill <weill@google.com>
Chauncy Cullitan <chauncyc@google.com>
Chen Zhihan <energiehund@gmail.com>
Cherry Zhang <cherryyz@google.com>
Chew Choon Keat <choonkeat@gmail.com>
Cholerae Hu <choleraehyq@gmail.com>
@@ -442,6 +448,7 @@ Christopher Cahoon <chris.cahoon@gmail.com>
Christopher Guiney <chris@guiney.net>
Christopher Henderson <chris@chenderson.org>
Christopher Koch <chrisko@google.com>
Christopher Loessl <cloessl+github@gmail.com>
Christopher Nelson <nadiasvertex@gmail.com>
Christopher Nielsen <m4dh4tt3r@gmail.com>
Christopher Redden <christopher.redden@gmail.com>
@@ -739,12 +746,14 @@ Frank Somers <fsomers@arista.com>
Frederic Guillot <frederic.guillot@gmail.com>
Frederick Kelly Mayle III <frederickmayle@gmail.com>
Frederik Ring <frederik.ring@gmail.com>
Frederik Zipp <fzipp@gmx.de>
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
Fredrik Forsmo <fredrik.forsmo@gmail.com>
Fredrik Wallgren <fredrik.wallgren@gmail.com>
Frew Schmidt <github@frew.co>
Frithjof Schulze <schulze@math.uni-hannover.de> <sfrithjof@gmail.com>
Frits van Bommel <fvbommel@gmail.com>
Fujimoto Kyosuke <kyoro.f@gmail.com>
Fumitoshi Ukai <ukai@google.com>
G. Hussain Chinoy <ghchinoy@gmail.com>
Gaal Yahas <gaal@google.com>
@@ -803,6 +812,7 @@ GitHub User @frennkie (6499251) <mail@rhab.de>
GitHub User @hengwu0 (41297446) <41297446+hengwu0@users.noreply.github.com>
GitHub User @itchyny (375258) <itchyny@hatena.ne.jp>
GitHub User @jinmiaoluo (39730824) <jinmiaoluo@icloud.com>
GitHub User @jopbrown (6345470) <msshane2008@gmail.com>
GitHub User @kazyshr (30496953) <kazyshr0301@gmail.com>
GitHub User @kc1212 (1093806) <kc1212@users.noreply.github.com>
GitHub User @Kropekk (13366453) <kamilkropiewnicki@gmail.com>
@@ -828,6 +838,7 @@ GitHub User @uhei (2116845) <uhei@users.noreply.github.com>
GitHub User @uropek (39370426) <uropek@gmail.com>
GitHub User @utkarsh-extc (53217283) <utkarsh.extc@gmail.com>
GitHub User @witchard (4994659) <witchard@hotmail.co.uk>
GitHub User @yah01 (12216890) <kagaminehuan@gmail.com>
GitHub User @yuanhh (1298735) <yuan415030@gmail.com>
GitHub User @zikaeroh (48577114) <zikaeroh@gmail.com>
GitHub User @ZZMarquis (7624583) <zhonglingjian3821@163.com>
@@ -897,6 +908,7 @@ Heschi Kreinick <heschi@google.com>
Hidetatsu Yaginuma <ygnmhdtt@gmail.com>
Hilko Bengen <bengen@hilluzination.de>
Hiroaki Nakamura <hnakamur@gmail.com>
Hiromichi Ema <ema.hiro@gmail.com>
Hironao OTSUBO <motemen@gmail.com>
Hiroshi Ioka <hirochachacha@gmail.com>
Hitoshi Mitake <mitake.hitoshi@gmail.com>
@@ -973,6 +985,7 @@ Jakob Borg <jakob@nym.se>
Jakob Weisblat <jakobw@mit.edu>
Jakub Čajka <jcajka@redhat.com>
Jakub Ryszard Czarnowicz <j.czarnowicz@gmail.com>
Jamal Carvalho <jamal.a.carvalho@gmail.com>
James Aguilar <jaguilar@google.com>
James Bardin <j.bardin@gmail.com>
James Chacon <jchacon@google.com>
@@ -1020,6 +1033,7 @@ Jannis Andrija Schnitzer <jannis@schnitzer.im>
Jared Culp <jculp14@gmail.com>
Jaroslavas Počepko <jp@webmaster.ms>
Jason A. Donenfeld <Jason@zx2c4.com>
Jason Baker <jason-baker@users.noreply.github.com>
Jason Barnett <jason.w.barnett@gmail.com>
Jason Buberel <jbuberel@google.com>
Jason Chu <jasonchujc@gmail.com>
@@ -1213,6 +1227,7 @@ Kamil Chmielewski <kamil.chm@gmail.com>
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
Kamil Rytarowski <krytarowski@users.noreply.github.com>
Kang Hu <hukangustc@gmail.com>
Kanta Ebihara <kantaebihara@gmail.com>
Karan Dhiman <karandhi@ca.ibm.com>
Karel Pazdera <pazderak@gmail.com>
Karoly Negyesi <chx1975@gmail.com>
@@ -1252,6 +1267,7 @@ Ketan Parmar <ketanbparmar@gmail.com>
Kevan Swanberg <kevswanberg@gmail.com>
Kevin Ballard <kevin@sb.org>
Kevin Burke <kev@inburke.com>
Kévin Dunglas <dunglas@gmail.com>
Kevin Gillette <extemporalgenome@gmail.com>
Kevin Kirsche <kev.kirsche@gmail.com>
Kevin Klues <klueska@gmail.com> <klueska@google.com>
@@ -1265,6 +1281,7 @@ Kim Yongbin <kybinz@gmail.com>
Kir Kolyshkin <kolyshkin@gmail.com>
Kirill Motkov <Motkov.Kirill@gmail.com>
Kirill Smelkov <kirr@nexedi.com>
Kirill Tatchihin <kirabsuir@gmail.com>
Kirk Han <kirk91.han@gmail.com>
Kirklin McDonald <kirklin.mcdonald@gmail.com>
Klaus Post <klauspost@gmail.com>
@@ -1378,6 +1395,7 @@ Marcelo E. Magallon <marcelo.magallon@gmail.com>
Marco Hennings <marco.hennings@freiheit.com>
Marcus Willock <crazcalm@gmail.com>
Marga Manterola <marga@google.com>
Mariano Cano <mariano@smallstep.com>
Marin Bašić <marin.basic02@gmail.com>
Mario Arranz <marioarranzr@gmail.com>
Marius A. Eriksen <marius@grailbio.com>
@@ -1949,6 +1967,7 @@ Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
Sergey Arseev <sergey.arseev@intel.com>
Sergey Dobrodey <sergey.dobrodey@synesis.ru>
Sergey Frolov <sfrolov@google.com>
Sergey Ivanov <ser1325@gmail.com>
Sergey Lukjanov <me@slukjanov.name>
Sergey Mishin <sergeymishine@gmail.com>
Sergey Mudrik <sergey.mudrik@gmail.com>
@@ -2090,6 +2109,7 @@ Thomas Desrosiers <thomasdesr@gmail.com>
Thomas Habets <habets@google.com>
Thomas Kappler <tkappler@gmail.com>
Thomas Meson <zllak@hycik.org>
Thomas Symborski <thomas.symborski@gmail.com>
Thomas Wanielista <tomwans@gmail.com>
Thorben Krueger <thorben.krueger@gmail.com>
Thordur Bjornsson <thorduri@secnorth.net>
@@ -2130,6 +2150,7 @@ Tom Thorogood <me+google@tomthorogood.co.uk>
Tom Wilkie <tom@weave.works>
Tomas Dabasinskas <tomas@dabasinskas.net>
Tommy Schaefer <tommy.schaefer@teecom.com>
Tomohiro Kusumoto <zabio1192@gmail.com>
Tomoya Ishizaki <zaq1tomo@gmail.com>
Tonis Tiigi <tonistiigi@gmail.com>
Tony Reix <tony.reix@bull.net>
@@ -2240,6 +2261,7 @@ Xi Ruoyao <xry23333@gmail.com>
Xia Bin <snyh@snyh.org>
Xiangdong Ji <xiangdong.ji@arm.com>
Xing Xing <mikespook@gmail.com>
Xingqang Bai <bxq2011hust@qq.com>
Xu Fei <badgangkiller@gmail.com>
Xudong Zhang <felixmelon@gmail.com>
Xudong Zheng <7pkvm5aw@slicealias.com>

1
VERSION Normal file
View File

@@ -0,0 +1 @@
go1.14.1

View File

@@ -395,3 +395,14 @@ func (w *Watchdog) Start() {
The cost of race detection varies by program, but for a typical program, memory
usage may increase by 5-10x and execution time by 2-20x.
</p>
<p>
The race detector currently allocates an extra 8 bytes per <code>defer</code>
and <code>recover</code> statement. Those extra allocations <a
href="https://golang.org/issue/26813">are not recovered until the goroutine
exits</a>. This means that if you have a long-running goroutine that is
periodically issuing <code>defer</code> and <code>recover</code> calls,
the program memory usage may grow without bound. These memory allocations
will not show up in the output of <code>runtime.ReadMemStats</code> or
<code>runtime/pprof</code>.
</p>

View File

@@ -34,6 +34,7 @@ We encourage all Go users to subscribe to
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
<ul>
<li><a href="/doc/go1.14">Go 1.14</a> <small>(February 2020)</small></li>
<li><a href="/doc/go1.13">Go 1.13</a> <small>(September 2019)</small></li>
<li><a href="/doc/go1.12">Go 1.12</a> <small>(February 2019)</small></li>
<li><a href="/doc/go1.11">Go 1.11</a> <small>(August 2018)</small></li>

View File

@@ -14,24 +14,24 @@ Do not send CLs removing the interior tags from such phrases.
main ul li { margin: 0.5em 0; }
</style>
<h2 id="introduction">DRAFT RELEASE NOTES — Introduction to Go 1.14</h2>
<h2 id="introduction">Introduction to Go 1.14</h2>
<p>
<strong>
Go 1.14 is not yet released. These are work-in-progress
release notes. Go 1.14 is expected to be released in February 2020.
</strong>
The latest Go release, version 1.14, arrives six months after <a href="go1.13">Go 1.13</a>.
Most of its changes are in the implementation of the toolchain, runtime, and libraries.
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
We expect almost all Go programs to continue to compile and run as before.
</p>
<p>
Module support in the <code>go</code> command is now ready for production use,
and we encourage all users to migrate to Go modules for dependency management.
If you are unable to migrate due to a problem in the Go toolchain,
please ensure that the problem has an
<a href="https://golang.org/issue?q=is%3Aissue+is%3Aopen+label%3Amodules">open issue</a>
filed. (If the issue is not on the <code>Go1.15</code> milestone, please let us
know why it prevents you from migrating so that we can prioritize it
appropriately.)
Module support in the <code>go</code> command is now ready for production use,
and we encourage all users to <a href="https://blog.golang.org/migrating-to-go-modules">migrate to Go
modules for dependency management</a>. If you are unable to migrate due to a problem in the Go
toolchain, please ensure that the problem has an
<a href="https://golang.org/issue?q=is%3Aissue+is%3Aopen+label%3Amodules">open issue</a>
filed. (If the issue is not on the <code>Go1.15</code> milestone, please let us
know why it prevents you from migrating so that we can prioritize it
appropriately.)
</p>
<h2 id="language">Changes to the language</h2>
@@ -77,6 +77,18 @@ appropriately.)
(Data Execution Prevention)</a> enabled.
</p>
<p><!-- CL 202439 -->
On Windows, creating a file
via <a href="/pkg/os#CreateFile"><code>os.OpenFile</code></a> with
the <a href="/pkg/os/#O_CREATE"><code>os.O_CREATE</code></a> flag, or
via <a href="/pkg/syscall#Open"><code>syscall.Open</code></a> with
the <a href="/pkg/syscall#O_CREAT"><code>syscall.O_CREAT</code></a>
flag, will now create the file as read-only if the
bit <code>0o200</code> (owner write permission) is not set in the
permission argument. This makes the behavior on Windows more like
that on Unix systems.
</p>
<h3 id="wasm">WebAssembly</h3>
<p><!-- CL 203600 -->
@@ -108,7 +120,7 @@ appropriately.)
<h3 id="freebsd">FreeBSD</h3>
<p><!-- CL 199919 -->
Go now supports the 64-bit ARM architecture on FreeBSD (the
Go now supports the 64-bit ARM architecture on FreeBSD 12.0 or later (the
<code>freebsd/arm64</code> port).
</p>
@@ -393,7 +405,7 @@ appropriately.)
<p><!-- CL 202117 -->
This release includes experimental support for compiler-inserted
coverage instrumentation for fuzzing.
See <a href="https://golang.org/issue/14565">the issue</a> for more
See <a href="https://golang.org/issue/14565">issue 14565</a> for more
details.
This API may change in future releases.
</p>
@@ -582,6 +594,13 @@ appropriately.)
was never a documented feature. For proper escaping, see <a
href="/pkg/encoding/json/#HTMLEscape"><code>HTMLEscape</code></a>.
</p>
<p><!-- CL 195045 -->
<a href="/pkg/encoding/json/#Number"><code>Number</code></a> no longer
accepts invalid numbers, to follow the documented behavior more closely.
If a program needs to accept invalid numbers like the empty string,
consider wrapping the type with <a href="/pkg/encoding/json/#Unmarshaler"><code>Unmarshaler</code></a>.
</p>
</dd>
</dl><!-- encoding/json -->
@@ -752,6 +771,19 @@ appropriately.)
</dd>
</dl><!-- net/textproto -->
<dl id="net/url"><dt><a href="/pkg/net/url/">net/url</a></dt>
<dd>
<p><!-- CL 185117 -->
When parsing of a URL fails
(for example by <a href="/pkg/net/url/#Parse"><code>Parse</code></a>
or <a href="/pkg/net/url/#ParseRequestURI"><code>ParseRequestURI</code></a>),
the resulting <a href="/pkg/net/url/#Error.Error"><code>Error</code></a> message
will now quote the unparsable URL.
This provides clearer structure and consistency with other parsing errors.
</p>
</dd>
</dl><!-- net/url -->
<dl id="os/signal"><dt><a href="/pkg/os/signal/">os/signal</a></dt>
<dd>
<p><!-- CL 187739 -->

View File

@@ -1,17 +1,41 @@
This directory contains helper file for trace viewer (`go tool trace`).
## Resources for Go's trace viewer
`trace_viewer_full.html` was generated by following
[instructions](https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md)
on revision `dc970d3e1f7b3da5a2849de70ff253acdb70148f`
of [catapult](https://github.com/catapult-project/catapult) using:
Go execution trace UI (`go tool trace`) embeds
Chrome's trace viewer (Catapult) following the
[instructions](
https://chromium.googlesource.com/catapult/+/refs/heads/master/tracing/docs/embedding-trace-viewer.md). This directory contains
the helper files to embed Chrome's trace viewer.
The current resources were generated/copied from
[`Catapult@9508452e18f130c98499cb4c4f1e1efaedee8962`](
https://chromium.googlesource.com/catapult/+/9508452e18f130c98499cb4c4f1e1efaedee8962).
### Updating `trace_viewer_full.html`
The file was generated by catapult's `vulcanize_trace_viewer` command.
```
catapult$ ./tracing/bin/vulcanize_trace_viewer --config=full
catapult$ cp tracing/bin/trace_viewer_full.html $GOROOT/misc/trace/trace_viewer_lean.html
$ git clone https://chromium.googlesource.com/catapult
$ cd catapult
$ ./tracing/bin/vulcanize_trace_viewer --config=full
$ cp tracing/bin/trace_viewer_full.html $GOROOT/misc/trace/trace_viewer_full.html
```
We are supposed to use --config=lean (produces smaller html),
but it is broken at the moment:
https://github.com/catapult-project/catapult/issues/2247
### Updating `webcomponents.min.js`
`webcomponents.min.js` is necessary to let the trace viewer page
to import the `trace_viewer_full.html`.
This is copied from the catapult repo.
```
$ cp third_party/polymer/components/webcomponentsjs/webcomponents.min.js $GOROOT/misc/trace/webcomponents.min.js
```
## Licenses
The license for trace-viewer is as follows:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
//
@@ -40,3 +64,42 @@ The license for trace-viewer is as follows:
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The license for webcomponents.min.js is as follows:
/**
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// Copyright (c) 2014 The Polymer Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

File diff suppressed because one or more lines are too long

14
misc/trace/webcomponents.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -186,6 +186,7 @@ func algtype1(t *types.Type) (AlgKind, *types.Type) {
// genhash returns a symbol which is the closure used to compute
// the hash of a value of type t.
// Note: the generated function must match runtime.typehash exactly.
func genhash(t *types.Type) *obj.LSym {
switch algtype(t) {
default:

View File

@@ -1224,6 +1224,14 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error {
if len(out) == 0 {
fmt.Fprintf(cmd.Stdout, "%s\n", err)
}
// NOTE(golang.org/issue/37555): test2json reports that a test passes
// unless "FAIL" is printed at the beginning of a line. The test may not
// actually print that if it panics, exits, or terminates abnormally,
// so we print it here. We can't always check whether it was printed
// because some tests need stdout to be a terminal (golang.org/issue/34791),
// not a pipe.
// TODO(golang.org/issue/29062): tests that exit with status 0 without
// printing a final result should fail.
fmt.Fprintf(cmd.Stdout, "FAIL\t%s\t%s\n", a.Package.ImportPath, t)
}

View File

@@ -213,6 +213,9 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
} else if cfg.BuildTrimpath && p.Module != nil {
fmt.Fprintf(h, "module %s@%s\n", p.Module.Path, p.Module.Version)
}
if p.Module != nil {
fmt.Fprintf(h, "go %s\n", p.Module.GoVersion)
}
fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
fmt.Fprintf(h, "import %q\n", p.ImportPath)
fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix)

View File

@@ -7,6 +7,13 @@ go mod edit -go=1.9
grep 'go 1.9' go.mod
go build
# Reverting the version should force a rebuild and error instead of using
# the cached 1.9 build. (https://golang.org/issue/37804)
go mod edit -go=1.8
! go build
stderr 'type aliases only supported as of'
-- go.mod --
module m
go 1.8

View File

@@ -0,0 +1,69 @@
# Verifies golang.org/issue/37555.
[short] skip
# 'go test -json' should say a test passes if it says it passes.
go test -json ./pass
stdout '"Action":"pass".*\n\z'
! stdout '"Test":.*\n\z'
# 'go test -json' should say a test passes if it exits 0 and prints nothing.
# TODO(golang.org/issue/29062): this should fail in the future.
go test -json ./exit0main
stdout '"Action":"pass".*\n\z'
! stdout '"Test":.*\n\z'
# 'go test -json' should say a test fails if it exits 1 and prints nothing.
! go test -json ./exit1main
stdout '"Action":"fail".*\n\z'
! stdout '"Test":.*\n\z'
# 'go test -json' should say a test fails if it panics.
! go test -json ./panic
stdout '"Action":"fail".*\n\z'
! stdout '"Test":.*\n\z'
-- go.mod --
module example.com/test
go 1.14
-- pass/pass_test.go --
package pass_test
import "testing"
func TestPass(t *testing.T) {}
-- exit0main/exit0main_test.go --
package exit0_test
import (
"os"
"testing"
)
func TestMain(m *testing.M) {
os.Exit(0)
}
-- exit1main/exit1main_test.go --
package exit1_test
import (
"os"
"testing"
)
func TestMain(m *testing.M) {
os.Exit(1)
}
-- panic/panic_test.go --
package panic_test
import "testing"
func TestPanic(t *testing.T) {
panic("oh no")
}

View File

@@ -128,9 +128,16 @@ func (c *converter) Write(b []byte) (int, error) {
}
var (
// printed by test on successful run.
bigPass = []byte("PASS\n")
// printed by test after a normal test failure.
bigFail = []byte("FAIL\n")
// printed by 'go test' along with an error if the test binary terminates
// with an error.
bigFailErrorPrefix = []byte("FAIL\t")
updates = [][]byte{
[]byte("=== RUN "),
[]byte("=== PAUSE "),
@@ -155,7 +162,7 @@ var (
// before or after emitting other events.
func (c *converter) handleInputLine(line []byte) {
// Final PASS or FAIL.
if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) {
if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) || bytes.HasPrefix(line, bigFailErrorPrefix) {
c.flushReport(0)
c.output.write(line)
if bytes.Equal(line, bigPass) {

View File

@@ -13,7 +13,7 @@
{"Action":"output","Test":"TestPanic","Output":"\tgo/src/testing/testing.go:909 +0xc9\n"}
{"Action":"output","Test":"TestPanic","Output":"created by testing.(*T).Run\n"}
{"Action":"output","Test":"TestPanic","Output":"\tgo/src/testing/testing.go:960 +0x350\n"}
{"Action":"output","Test":"TestPanic","Output":"FAIL\tcommand-line-arguments\t0.042s\n"}
{"Action":"fail","Test":"TestPanic"}
{"Action":"output","Output":"FAIL\tcommand-line-arguments\t0.042s\n"}
{"Action":"output","Output":"FAIL\n"}
{"Action":"fail"}

View File

@@ -25,6 +25,7 @@ func init() {
http.HandleFunc("/trace", httpTrace)
http.HandleFunc("/jsontrace", httpJsonTrace)
http.HandleFunc("/trace_viewer_html", httpTraceViewerHTML)
http.HandleFunc("/webcomponents.min.js", webcomponentsJS)
}
// httpTrace serves either whole trace (goid==0) or trace for goid goroutine.
@@ -43,14 +44,26 @@ func httpTrace(w http.ResponseWriter, r *http.Request) {
}
// See https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md
// This is almost verbatim copy of:
// https://github.com/catapult-project/catapult/blob/master/tracing/bin/index.html
// on revision 5f9e4c3eaa555bdef18218a89f38c768303b7b6e.
// https://chromium.googlesource.com/catapult/+/9508452e18f130c98499cb4c4f1e1efaedee8962/tracing/docs/embedding-trace-viewer.md
// This is almost verbatim copy of https://chromium-review.googlesource.com/c/catapult/+/2062938/2/tracing/bin/index.html
var templTrace = `
<html>
<head>
<link href="/trace_viewer_html" rel="import">
<script src="/webcomponents.min.js"></script>
<script>
'use strict';
function onTraceViewerImportFail() {
document.addEventListener('DOMContentLoaded', function() {
document.body.textContent =
'/trace_viewer_full.html is missing. File a bug in https://golang.org/issue';
});
}
</script>
<link rel="import" href="/trace_viewer_html"
onerror="onTraceViewerImportFail(event)">
<style type="text/css">
html, body {
box-sizing: border-box;
@@ -77,10 +90,10 @@ var templTrace = `
function load() {
var req = new XMLHttpRequest();
var is_binary = /[.]gz$/.test(url) || /[.]zip$/.test(url);
var isBinary = /[.]gz$/.test(url) || /[.]zip$/.test(url);
req.overrideMimeType('text/plain; charset=x-user-defined');
req.open('GET', url, true);
if (is_binary)
if (isBinary)
req.responseType = 'arraybuffer';
req.onreadystatechange = function(event) {
@@ -89,7 +102,7 @@ var templTrace = `
window.setTimeout(function() {
if (req.status === 200)
onResult(is_binary ? req.response : req.responseText);
onResult(isBinary ? req.response : req.responseText);
else
onResultFail(req.status);
}, 0);
@@ -136,17 +149,17 @@ var templTrace = `
overlay.visible = true;
}
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('WebComponentsReady', function() {
var container = document.createElement('track-view-container');
container.id = 'track_view_container';
viewer = document.createElement('tr-ui-timeline-view');
viewer.track_view_container = container;
viewer.appendChild(container);
Polymer.dom(viewer).appendChild(container);
viewer.id = 'trace-viewer';
viewer.globalMode = true;
document.body.appendChild(viewer);
Polymer.dom(document.body).appendChild(viewer);
url = '/jsontrace?{{PARAMS}}';
load();
@@ -165,6 +178,10 @@ func httpTraceViewerHTML(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, filepath.Join(runtime.GOROOT(), "misc", "trace", "trace_viewer_full.html"))
}
func webcomponentsJS(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, filepath.Join(runtime.GOROOT(), "misc", "trace", "webcomponents.min.js"))
}
// httpJsonTrace serves json trace, requested from within templTrace HTML.
func httpJsonTrace(w http.ResponseWriter, r *http.Request) {
defer debug.FreeOSMemory()

View File

@@ -86,7 +86,8 @@ func NewGCM(cipher Block) (AEAD, error) {
}
// NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois
// Counter Mode, which accepts nonces of the given length.
// Counter Mode, which accepts nonces of the given length. The length must not
// be zero.
//
// Only use this function if you require compatibility with an existing
// cryptosystem that uses non-standard nonce lengths. All other users should use
@@ -112,6 +113,10 @@ func newGCMWithNonceAndTagSize(cipher Block, nonceSize, tagSize int) (AEAD, erro
return nil, errors.New("cipher: incorrect tag size given to GCM")
}
if nonceSize <= 0 {
return nil, errors.New("cipher: the nonce can't have zero length, or the security of the key will be immediately compromised")
}
if cipher, ok := cipher.(gcmAble); ok {
return cipher.NewGCM(nonceSize, tagSize)
}

View File

@@ -217,6 +217,13 @@ var aesGCMTests = []struct {
"2b9680b886b3efb7c6354b38c63b5373",
"e2b7e5ed5ff27fc8664148f5a628a46dcbf2015184fffb82f2651c36",
},
{
"11754cd72aec309bf52f7687212e8957",
"",
"",
"",
"250327c674aaf477aef2675748cf6971",
},
}
func TestAESGCM(t *testing.T) {
@@ -234,14 +241,22 @@ func TestAESGCM(t *testing.T) {
var aesgcm cipher.AEAD
switch {
// Handle non-standard nonce sizes
// Handle non-standard tag sizes
case tagSize != 16:
aesgcm, err = cipher.NewGCMWithTagSize(aes, tagSize)
if err != nil {
t.Fatal(err)
}
// Handle non-standard tag sizes
// Handle 0 nonce size (expect error and continue)
case len(nonce) == 0:
aesgcm, err = cipher.NewGCMWithNonceSize(aes, 0)
if err == nil {
t.Fatal("expected error for zero nonce size")
}
continue
// Handle non-standard nonce sizes
case len(nonce) != 12:
aesgcm, err = cipher.NewGCMWithNonceSize(aes, len(nonce))
if err != nil {

View File

@@ -69,7 +69,7 @@ type Hash struct {
// which does call h.initSeed.)
func (h *Hash) initSeed() {
if h.seed.s == 0 {
h.SetSeed(MakeSeed())
h.setSeed(MakeSeed())
}
}
@@ -124,12 +124,17 @@ func (h *Hash) Seed() Seed {
// Two Hash objects with different seeds will very likely behave differently.
// Any bytes added to h before this call will be discarded.
func (h *Hash) SetSeed(seed Seed) {
h.setSeed(seed)
h.n = 0
}
// setSeed sets seed without discarding accumulated data.
func (h *Hash) setSeed(seed Seed) {
if seed.s == 0 {
panic("maphash: use of uninitialized Seed")
}
h.seed = seed
h.state = seed
h.n = 0
}
// Reset discards all bytes added to h.

View File

@@ -83,6 +83,29 @@ func TestHashHighBytes(t *testing.T) {
}
}
func TestRepeat(t *testing.T) {
h1 := new(Hash)
h1.WriteString("testing")
sum1 := h1.Sum64()
h1.Reset()
h1.WriteString("testing")
sum2 := h1.Sum64()
if sum1 != sum2 {
t.Errorf("different sum after reseting: %#x != %#x", sum1, sum2)
}
h2 := new(Hash)
h2.SetSeed(h1.Seed())
h2.WriteString("testing")
sum3 := h2.Sum64()
if sum1 != sum3 {
t.Errorf("different sum on the same seed: %#x != %#x", sum1, sum3)
}
}
// Make sure a Hash implements the hash.Hash and hash.Hash64 interfaces.
var _ hash.Hash = &Hash{}
var _ hash.Hash64 = &Hash{}

View File

@@ -158,9 +158,19 @@ func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
// is slower but more general and is used for hashing interface types
// (called from interhash or nilinterhash, above) or for hashing in
// maps generated by reflect.MapOf (reflect_typehash, below).
// Note: this function must match the compiler generated
// functions exactly. See issue 37716.
func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
if t.tflag&tflagRegularMemory != 0 {
return memhash(p, h, t.size)
// Handle ptr sizes specially, see issue 37086.
switch t.size {
case 4:
return memhash32(p, h)
case 8:
return memhash64(p, h)
default:
return memhash(p, h, t.size)
}
}
switch t.kind & kindMask {
case kindFloat32:
@@ -187,12 +197,28 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
return h
case kindStruct:
s := (*structtype)(unsafe.Pointer(t))
memStart := uintptr(0)
memEnd := uintptr(0)
for _, f := range s.fields {
// TODO: maybe we could hash several contiguous fields all at once.
if memEnd > memStart && (f.name.isBlank() || f.offset() != memEnd || f.typ.tflag&tflagRegularMemory == 0) {
// flush any pending regular memory hashing
h = memhash(add(p, memStart), h, memEnd-memStart)
memStart = memEnd
}
if f.name.isBlank() {
continue
}
h = typehash(f.typ, add(p, f.offset()), h)
if f.typ.tflag&tflagRegularMemory == 0 {
h = typehash(f.typ, add(p, f.offset()), h)
continue
}
if memStart == memEnd {
memStart = f.offset()
}
memEnd = f.offset() + f.typ.size
}
if memEnd > memStart {
h = memhash(add(p, memStart), h, memEnd-memStart)
}
return h
default:

View File

@@ -8,8 +8,10 @@ import "unsafe"
func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
// Check that (*[n]elem)(p) is appropriately aligned.
// Note that we allow unaligned pointers if the types they point to contain
// no pointers themselves. See issue 37298.
// TODO(mdempsky): What about fieldAlign?
if uintptr(p)&(uintptr(elem.align)-1) != 0 {
if elem.ptrdata != 0 && uintptr(p)&(uintptr(elem.align)-1) != 0 {
throw("checkptr: unsafe pointer conversion")
}

View File

@@ -24,7 +24,8 @@ func TestCheckPtr(t *testing.T) {
cmd string
want string
}{
{"CheckPtrAlignment", "fatal error: checkptr: unsafe pointer conversion\n"},
{"CheckPtrAlignmentPtr", "fatal error: checkptr: unsafe pointer conversion\n"},
{"CheckPtrAlignmentNoPtr", ""},
{"CheckPtrArithmetic", "fatal error: checkptr: unsafe pointer arithmetic\n"},
{"CheckPtrSize", "fatal error: checkptr: unsafe pointer conversion\n"},
{"CheckPtrSmall", "fatal error: checkptr: unsafe pointer arithmetic\n"},
@@ -38,6 +39,12 @@ func TestCheckPtr(t *testing.T) {
if err != nil {
t.Log(err)
}
if tc.want == "" {
if len(got) > 0 {
t.Errorf("output:\n%s\nwant no output", got)
}
return
}
if !strings.HasPrefix(string(got), tc.want) {
t.Errorf("output:\n%s\n\nwant output starting with: %s", got, tc.want)
}

View File

@@ -11,6 +11,7 @@ import (
// Offsets into internal/cpu records for use in assembly.
const (
offsetX86HasAVX = unsafe.Offsetof(cpu.X86.HasAVX)
offsetX86HasAVX2 = unsafe.Offsetof(cpu.X86.HasAVX2)
offsetX86HasERMS = unsafe.Offsetof(cpu.X86.HasERMS)
offsetX86HasSSE2 = unsafe.Offsetof(cpu.X86.HasSSE2)

View File

@@ -6,6 +6,7 @@ package runtime_test
import (
"fmt"
"os"
"reflect"
"runtime"
"testing"
@@ -281,3 +282,56 @@ func TestDeferForFuncWithNoExit(t *testing.T) {
for {
}
}
// Test case approximating issue #37664, where a recursive function (interpreter)
// may do repeated recovers/re-panics until it reaches the frame where the panic
// can actually be handled. The recurseFnPanicRec() function is testing that there
// are no stale defer structs on the defer chain after the interpreter() sequence,
// by writing a bunch of 0xffffffffs into several recursive stack frames, and then
// doing a single panic-recover which would invoke any such stale defer structs.
func TestDeferWithRepeatedRepanics(t *testing.T) {
interpreter(0, 6, 2)
recurseFnPanicRec(0, 10)
interpreter(0, 5, 1)
recurseFnPanicRec(0, 10)
interpreter(0, 6, 3)
recurseFnPanicRec(0, 10)
}
func interpreter(level int, maxlevel int, rec int) {
defer func() {
e := recover()
if e == nil {
return
}
if level != e.(int) {
//fmt.Fprintln(os.Stderr, "re-panicing, level", level)
panic(e)
}
//fmt.Fprintln(os.Stderr, "Recovered, level", level)
}()
if level+1 < maxlevel {
interpreter(level+1, maxlevel, rec)
} else {
//fmt.Fprintln(os.Stderr, "Initiating panic")
panic(rec)
}
}
func recurseFnPanicRec(level int, maxlevel int) {
defer func() {
recover()
}()
recurseFn(level, maxlevel)
}
func recurseFn(level int, maxlevel int) {
a := [40]uint32{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}
if level+1 < maxlevel {
// Need this print statement to keep a around. '_ = a[4]' doesn't do it.
fmt.Fprintln(os.Stderr, "recurseFn", level, a[4])
recurseFn(level+1, maxlevel)
} else {
panic("recurseFn panic")
}
}

View File

@@ -950,3 +950,28 @@ func SemNwait(addr *uint32) uint32 {
root := semroot(addr)
return atomic.Load(&root.nwait)
}
// MapHashCheck computes the hash of the key k for the map m, twice.
// Method 1 uses the built-in hasher for the map.
// Method 2 uses the typehash function (the one used by reflect).
// Returns the two hash values, which should always be equal.
func MapHashCheck(m interface{}, k interface{}) (uintptr, uintptr) {
// Unpack m.
mt := (*maptype)(unsafe.Pointer(efaceOf(&m)._type))
mh := (*hmap)(efaceOf(&m).data)
// Unpack k.
kt := efaceOf(&k)._type
var p unsafe.Pointer
if isDirectIface(kt) {
q := efaceOf(&k).data
p = unsafe.Pointer(&q)
} else {
p = efaceOf(&k).data
}
// Compute the hash functions.
x := mt.hasher(noescape(p), uintptr(mh.hash0))
y := typehash(kt, noescape(p), uintptr(mh.hash0))
return x, y
}

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"math"
"math/rand"
"reflect"
. "runtime"
"strings"
"testing"
@@ -48,6 +49,54 @@ func TestMemHash64Equality(t *testing.T) {
}
}
func TestCompilerVsRuntimeHash(t *testing.T) {
// Test to make sure the compiler's hash function and the runtime's hash function agree.
// See issue 37716.
for _, m := range []interface{}{
map[bool]int{},
map[int8]int{},
map[uint8]int{},
map[int16]int{},
map[uint16]int{},
map[int32]int{},
map[uint32]int{},
map[int64]int{},
map[uint64]int{},
map[int]int{},
map[uint]int{},
map[uintptr]int{},
map[*byte]int{},
map[chan int]int{},
map[unsafe.Pointer]int{},
map[float32]int{},
map[float64]int{},
map[complex64]int{},
map[complex128]int{},
map[string]int{},
//map[interface{}]int{},
//map[interface{F()}]int{},
map[[8]uint64]int{},
map[[8]string]int{},
map[struct{ a, b, c, d int32 }]int{}, // Note: tests AMEM128
map[struct{ a, b, _, d int32 }]int{},
map[struct {
a, b int32
c float32
d, e [8]byte
}]int{},
map[struct {
a int16
b int64
}]int{},
} {
k := reflect.New(reflect.TypeOf(m).Key()).Elem().Interface() // the zero key
x, y := MapHashCheck(m, k)
if x != y {
t.Errorf("hashes did not match (%x vs %x) for map %T", x, y, m)
}
}
}
// Smhasher is a torture test for hash functions.
// https://code.google.com/p/smhasher/
// This code is a port of some of the Smhasher tests to Go.

View File

@@ -244,15 +244,6 @@ func genAMD64() {
// TODO: MXCSR register?
// Apparently, the signal handling code path in darwin kernel leaves
// the upper bits of Y registers in a dirty state, which causes
// many SSE operations (128-bit and narrower) become much slower.
// Clear the upper bits to get to a clean state. See issue #37174.
// It is safe here as Go code don't use the upper bits of Y registers.
p("#ifdef GOOS_darwin")
p("VZEROUPPER")
p("#endif")
p("PUSHQ BP")
p("MOVQ SP, BP")
p("// Save flags before clobbering them")
@@ -261,6 +252,18 @@ func genAMD64() {
p("ADJSP $%d", l.stack)
p("// But vet doesn't know ADJSP, so suppress vet stack checking")
p("NOP SP")
// Apparently, the signal handling code path in darwin kernel leaves
// the upper bits of Y registers in a dirty state, which causes
// many SSE operations (128-bit and narrower) become much slower.
// Clear the upper bits to get to a clean state. See issue #37174.
// It is safe here as Go code don't use the upper bits of Y registers.
p("#ifdef GOOS_darwin")
p("CMPB internalcpu·X86+const_offsetX86HasAVX(SB), $0")
p("JE 2(PC)")
p("VZEROUPPER")
p("#endif")
l.save()
p("CALL ·asyncPreempt2(SB)")
l.restore()
@@ -379,6 +382,7 @@ func genMIPS(_64bit bool) {
sub := "SUB"
r28 := "R28"
regsize := 4
softfloat := "GOMIPS_softfloat"
if _64bit {
mov = "MOVV"
movf = "MOVD"
@@ -386,6 +390,7 @@ func genMIPS(_64bit bool) {
sub = "SUBV"
r28 = "RSB"
regsize = 8
softfloat = "GOMIPS64_softfloat"
}
// Add integer registers R1-R22, R24-R25, R28
@@ -408,28 +413,36 @@ func genMIPS(_64bit bool) {
mov+" LO, R1\n"+mov+" R1, %d(R29)",
mov+" %d(R29), R1\n"+mov+" R1, LO",
regsize)
// Add floating point control/status register FCR31 (FCR0-FCR30 are irrelevant)
l.addSpecial(
var lfp = layout{sp: "R29", stack: l.stack}
lfp.addSpecial(
mov+" FCR31, R1\n"+mov+" R1, %d(R29)",
mov+" %d(R29), R1\n"+mov+" R1, FCR31",
regsize)
// Add floating point registers F0-F31.
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
l.add(movf, reg, regsize)
lfp.add(movf, reg, regsize)
}
// allocate frame, save PC of interrupted instruction (in LR)
p(mov+" R31, -%d(R29)", l.stack)
p(sub+" $%d, R29", l.stack)
p(mov+" R31, -%d(R29)", lfp.stack)
p(sub+" $%d, R29", lfp.stack)
l.save()
p("#ifndef %s", softfloat)
lfp.save()
p("#endif")
p("CALL ·asyncPreempt2(SB)")
p("#ifndef %s", softfloat)
lfp.restore()
p("#endif")
l.restore()
p(mov+" %d(R29), R31", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
p(mov + " (R29), R23") // load PC to REGTMP
p(add+" $%d, R29", l.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall)
p(mov+" %d(R29), R31", lfp.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
p(mov + " (R29), R23") // load PC to REGTMP
p(add+" $%d, R29", lfp.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall)
p("JMP (R23)")
}

View File

@@ -5,6 +5,7 @@
package runtime
import (
"runtime/internal/atomic"
"runtime/internal/sys"
"unsafe"
)
@@ -479,7 +480,21 @@ func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
func getpid() int
func tgkill(tgid, tid, sig int)
// touchStackBeforeSignal stores an errno value. If non-zero, it means
// that we should touch the signal stack before sending a signal.
// This is used on systems that have a bug when the signal stack must
// be faulted in. See #35777 and #37436.
//
// This is accessed atomically as it is set and read in different threads.
//
// TODO(austin): Remove this after Go 1.15 when we remove the
// mlockGsignal workaround.
var touchStackBeforeSignal uint32
// signalM sends a signal to mp.
func signalM(mp *m, sig int) {
if atomic.Load(&touchStackBeforeSignal) != 0 {
atomic.Cas((*uint32)(unsafe.Pointer(mp.gsignal.stack.hi-4)), 0, 0)
}
tgkill(getpid(), int(mp.procid), sig)
}

View File

@@ -7,6 +7,8 @@
package runtime
import "runtime/internal/atomic"
//go:noescape
func uname(utsname *new_utsname) int
@@ -58,17 +60,34 @@ func osArchInit() {
if m0.gsignal != nil {
throw("gsignal quirk too late")
}
throwReportQuirk = throwBadKernel
}
}
func mlockGsignal(gsignal *g) {
if err := mlock(gsignal.stack.hi-physPageSize, physPageSize); err < 0 {
printlock()
println("runtime: mlock of signal stack failed:", -err)
if err == -_ENOMEM {
println("runtime: increase the mlock limit (ulimit -l) or")
}
println("runtime: update your kernel to 5.3.15+, 5.4.2+, or 5.5+")
throw("mlock failed")
if atomic.Load(&touchStackBeforeSignal) != 0 {
// mlock has already failed, don't try again.
return
}
// This mlock call may fail, but we don't report the failure.
// Instead, if something goes badly wrong, we rely on prepareSignalM
// and throwBadKernel to do further mitigation and to report a problem
// to the user if mitigation fails. This is because many
// systems have a limit on the total mlock size, and many kernels
// that appear to have bad versions are actually patched to avoid the
// bug described above. We want Go 1.14 to run on those systems.
// See #37436.
if errno := mlock(gsignal.stack.hi-physPageSize, physPageSize); errno < 0 {
atomic.Store(&touchStackBeforeSignal, uint32(-errno))
}
}
// throwBadKernel is called, via throwReportQuirk, by throw.
func throwBadKernel() {
if errno := atomic.Load(&touchStackBeforeSignal); errno != 0 {
println("runtime: note: your Linux kernel may be buggy")
println("runtime: note: see https://golang.org/wiki/LinuxKernelSignalVectorBug")
println("runtime: note: mlock workaround for kernel bug failed with errno", errno)
}
}

View File

@@ -1003,11 +1003,12 @@ func gopanic(e interface{}) {
atomic.Xadd(&runningPanicDefers, -1)
if done {
// Remove any remaining non-started, open-coded defer
// entry after a recover (there's at most one, if we just
// ran a non-open-coded defer), since the entry will
// become out-dated and the defer will be executed
// normally.
// Remove any remaining non-started, open-coded
// defer entries after a recover, since the
// corresponding defers will be executed normally
// (inline). Any such entry will become stale once
// we run the corresponding defers inline and exit
// the associated stack frame.
d := gp._defer
var prev *_defer
for d != nil {
@@ -1025,8 +1026,9 @@ func gopanic(e interface{}) {
} else {
prev.link = d.link
}
newd := d.link
freedefer(d)
break
d = newd
} else {
prev = d
d = d.link
@@ -1279,6 +1281,12 @@ func startpanic_m() bool {
}
}
// throwReportQuirk, if non-nil, is called by throw after dumping the stacks.
//
// TODO(austin): Remove this after Go 1.15 when we remove the
// mlockGsignal workaround.
var throwReportQuirk func()
var didothers bool
var deadlock mutex
@@ -1325,6 +1333,10 @@ func dopanic_m(gp *g, pc, sp uintptr) bool {
printDebugLog()
if throwReportQuirk != nil {
throwReportQuirk()
}
return docrash
}

View File

@@ -68,7 +68,8 @@ Search:
if len(m.freeStk) < len(stk) {
m.freeStk = make([]uintptr, 1024)
}
e.stk = m.freeStk[:len(stk)]
// Limit cap to prevent append from clobbering freeStk.
e.stk = m.freeStk[:len(stk):len(stk)]
m.freeStk = m.freeStk[len(stk):]
for j := range stk {

View File

@@ -1172,16 +1172,25 @@ func TestTryAdd(t *testing.T) {
{Value: []int64{20, 20 * period}, Location: []*profile.Location{{ID: 1}}},
},
}, {
name: "recursive_inlined_funcs",
// If a function is called recursively then it must not be
// inlined in the caller.
//
// N.B. We're generating an impossible profile here, with a
// recursive inlineCallee call. This is simulating a non-Go
// function that looks like an inlined Go function other than
// its recursive property. See pcDeck.tryAdd.
name: "recursive_func_is_not_inlined",
input: []uint64{
3, 0, 500, // hz = 500. Must match the period.
5, 0, 30, inlinedCalleePtr, inlinedCalleePtr,
4, 0, 40, inlinedCalleePtr,
},
wantLocs: [][]string{{"runtime/pprof.inlinedCallee"}},
// inlinedCaller shows up here because
// runtime_expandFinalInlineFrame adds it to the stack frame.
wantLocs: [][]string{{"runtime/pprof.inlinedCallee"}, {"runtime/pprof.inlinedCaller"}},
wantSamples: []*profile.Sample{
{Value: []int64{30, 30 * period}, Location: []*profile.Location{{ID: 1}, {ID: 1}}},
{Value: []int64{40, 40 * period}, Location: []*profile.Location{{ID: 1}}},
{Value: []int64{30, 30 * period}, Location: []*profile.Location{{ID: 1}, {ID: 1}, {ID: 2}}},
{Value: []int64{40, 40 * period}, Location: []*profile.Location{{ID: 1}, {ID: 2}}},
},
}, {
name: "truncated_stack_trace_later",
@@ -1202,12 +1211,36 @@ func TestTryAdd(t *testing.T) {
4, 0, 70, inlinedCalleePtr,
5, 0, 80, inlinedCalleePtr, inlinedCallerPtr,
},
wantLocs: [][]string{ // the inline info is screwed up, but better than a crash.
{"runtime/pprof.inlinedCallee"},
wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}},
wantSamples: []*profile.Sample{
{Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}},
{Value: []int64{80, 80 * period}, Location: []*profile.Location{{ID: 1}}},
},
}, {
// We can recover the inlined caller from a truncated stack.
name: "truncated_stack_trace_only",
input: []uint64{
3, 0, 500, // hz = 500. Must match the period.
4, 0, 70, inlinedCalleePtr,
},
wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}},
wantSamples: []*profile.Sample{
{Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}},
},
}, {
// The same location is used for duplicated stacks.
name: "truncated_stack_trace_twice",
input: []uint64{
3, 0, 500, // hz = 500. Must match the period.
4, 0, 70, inlinedCalleePtr,
5, 0, 80, inlinedCallerPtr, inlinedCalleePtr,
},
wantLocs: [][]string{
{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"},
{"runtime/pprof.inlinedCaller"}},
wantSamples: []*profile.Sample{
{Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}},
{Value: []int64{80, 80 * period}, Location: []*profile.Location{{ID: 1}, {ID: 2}}},
{Value: []int64{80, 80 * period}, Location: []*profile.Location{{ID: 2}, {ID: 1}}},
},
}}

View File

@@ -384,6 +384,10 @@ func (b *profileBuilder) build() {
// It may emit to b.pb, so there must be no message encoding in progress.
func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLocs []uint64) {
b.deck.reset()
// The last frame might be truncated. Recover lost inline frames.
stk = runtime_expandFinalInlineFrame(stk)
for len(stk) > 0 {
addr := stk[0]
if l, ok := b.locs[addr]; ok {
@@ -395,22 +399,12 @@ func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLo
// then, record the cached location.
locs = append(locs, l.id)
// The stk may be truncated due to the stack depth limit
// (e.g. See maxStack and maxCPUProfStack in runtime) or
// bugs in runtime. Avoid the crash in either case.
// TODO(hyangah): The correct fix may require using the exact
// pcs as the key for b.locs cache management instead of just
// relying on the very first pc. We are late in the go1.14 dev
// cycle, so this is a workaround with little code change.
if len(l.pcs) > len(stk) {
stk = nil
// TODO(hyangah): would be nice if we can enable
// debug print out on demand and report the problematic
// cached location entry and stack traces. Do we already
// have such facility to utilize (e.g. GODEBUG)?
} else {
stk = stk[len(l.pcs):] // skip the matching pcs.
}
// Skip the matching pcs.
//
// Even if stk was truncated due to the stack depth
// limit, expandFinalInlineFrame above has already
// fixed the truncation, ensuring it is long enough.
stk = stk[len(l.pcs):]
continue
}
@@ -427,9 +421,9 @@ func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLo
stk = stk[1:]
continue
}
// add failed because this addr is not inlined with
// the existing PCs in the deck. Flush the deck and retry to
// handle this pc.
// add failed because this addr is not inlined with the
// existing PCs in the deck. Flush the deck and retry handling
// this pc.
if id := b.emitLocation(); id > 0 {
locs = append(locs, id)
}
@@ -463,8 +457,8 @@ func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLo
// the fake pcs and restore the inlined and entry functions. Inlined functions
// have the following properties:
// Frame's Func is nil (note: also true for non-Go functions), and
// Frame's Entry matches its entry function frame's Entry. (note: could also be true for recursive calls and non-Go functions),
// Frame's Name does not match its entry function frame's name.
// Frame's Entry matches its entry function frame's Entry (note: could also be true for recursive calls and non-Go functions), and
// Frame's Name does not match its entry function frame's name (note: inlined functions cannot be recursive).
//
// As reading and processing the pcs in a stack trace one by one (from leaf to the root),
// we use pcDeck to temporarily hold the observed pcs and their expanded frames
@@ -486,8 +480,8 @@ func (d *pcDeck) reset() {
// to the deck. If it fails the caller needs to flush the deck and retry.
func (d *pcDeck) tryAdd(pc uintptr, frames []runtime.Frame, symbolizeResult symbolizeFlag) (success bool) {
if existing := len(d.pcs); existing > 0 {
// 'frames' are all expanded from one 'pc' and represent all inlined functions
// so we check only the last one.
// 'd.frames' are all expanded from one 'pc' and represent all
// inlined functions so we check only the last one.
newFrame := frames[0]
last := d.frames[existing-1]
if last.Func != nil { // the last frame can't be inlined. Flush.

View File

@@ -9,6 +9,9 @@ import (
"unsafe"
)
// runtime_expandFinalInlineFrame is defined in runtime/symtab.go.
func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr
// runtime_setProfLabel is defined in runtime/proflabel.go.
func runtime_setProfLabel(labels unsafe.Pointer)

View File

@@ -4,9 +4,6 @@
#include "textflag.h"
TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
#ifdef GOOS_darwin
VZEROUPPER
#endif
PUSHQ BP
MOVQ SP, BP
// Save flags before clobbering them
@@ -15,6 +12,11 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
ADJSP $368
// But vet doesn't know ADJSP, so suppress vet stack checking
NOP SP
#ifdef GOOS_darwin
CMPB internalcpu·X86+const_offsetX86HasAVX(SB), $0
JE 2(PC)
VZEROUPPER
#endif
MOVQ AX, 0(SP)
MOVQ CX, 8(SP)
MOVQ DX, 16(SP)

View File

@@ -37,6 +37,7 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVV R1, 208(R29)
MOVV LO, R1
MOVV R1, 216(R29)
#ifndef GOMIPS64_softfloat
MOVV FCR31, R1
MOVV R1, 224(R29)
MOVD F0, 232(R29)
@@ -71,7 +72,9 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVD F29, 464(R29)
MOVD F30, 472(R29)
MOVD F31, 480(R29)
#endif
CALL ·asyncPreempt2(SB)
#ifndef GOMIPS64_softfloat
MOVD 480(R29), F31
MOVD 472(R29), F30
MOVD 464(R29), F29
@@ -106,6 +109,7 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVD 232(R29), F0
MOVV 224(R29), R1
MOVV R1, FCR31
#endif
MOVV 216(R29), R1
MOVV R1, LO
MOVV 208(R29), R1

View File

@@ -37,6 +37,7 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVW R1, 104(R29)
MOVW LO, R1
MOVW R1, 108(R29)
#ifndef GOMIPS_softfloat
MOVW FCR31, R1
MOVW R1, 112(R29)
MOVF F0, 116(R29)
@@ -71,7 +72,9 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVF F29, 232(R29)
MOVF F30, 236(R29)
MOVF F31, 240(R29)
#endif
CALL ·asyncPreempt2(SB)
#ifndef GOMIPS_softfloat
MOVF 240(R29), F31
MOVF 236(R29), F30
MOVF 232(R29), F29
@@ -106,6 +109,7 @@ TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVF 116(R29), F0
MOVW 112(R29), R1
MOVW R1, FCR31
#endif
MOVW 108(R29), R1
MOVW R1, LO
MOVW 104(R29), R1

View File

@@ -540,6 +540,10 @@ type m struct {
// requested, but fails. Accessed atomically.
preemptGen uint32
// Whether this is a pending preemption signal on this M.
// Accessed atomically.
signalPending uint32
dlogPerM
mOS

View File

@@ -333,6 +333,7 @@ func doSigPreempt(gp *g, ctxt *sigctxt) {
// Acknowledge the preemption.
atomic.Xadd(&gp.m.preemptGen, 1)
atomic.Store(&gp.m.signalPending, 0)
}
const preemptMSupported = pushCallSupported
@@ -359,7 +360,14 @@ func preemptM(mp *m) {
// required).
return
}
signalM(mp, sigPreempt)
if atomic.Cas(&mp.signalPending, 0, 1) {
// If multiple threads are preempting the same M, it may send many
// signals to the same M such that it hardly make progress, causing
// live-lock problem. Apparently this could happen on darwin. See
// issue #37741.
// Only send a signal if there isn't already one pending.
signalM(mp, sigPreempt)
}
}
// sigFetchG fetches the value of G safely when running in a signal handler.

View File

@@ -148,6 +148,59 @@ func (ci *Frames) Next() (frame Frame, more bool) {
return
}
// runtime_expandFinalInlineFrame expands the final pc in stk to include all
// "callers" if pc is inline.
//
//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame
func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
pc := stk[len(stk)-1]
tracepc := pc - 1
f := findfunc(tracepc)
if !f.valid() {
// Not a Go function.
return stk
}
inldata := funcdata(f, _FUNCDATA_InlTree)
if inldata == nil {
// Nothing inline in f.
return stk
}
// Treat the previous func as normal. We haven't actually checked, but
// since this pc was included in the stack, we know it shouldn't be
// elided.
lastFuncID := funcID_normal
// Remove pc from stk; we'll re-add it below.
stk = stk[:len(stk)-1]
// See inline expansion in gentraceback.
var cache pcvalueCache
inltree := (*[1 << 20]inlinedCall)(inldata)
for {
ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, &cache)
if ix < 0 {
break
}
if inltree[ix].funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
// ignore wrappers
} else {
stk = append(stk, pc)
}
lastFuncID = inltree[ix].funcID
// Back up to an instruction in the "caller".
tracepc = f.entry + uintptr(inltree[ix].parentPc)
pc = tracepc + 1
}
// N.B. we want to keep the last parentPC which is not inline.
stk = append(stk, pc)
return stk
}
// expandCgoFrames expands frame information for pc, known to be
// a non-Go function, using the cgoSymbolizer hook. expandCgoFrames
// returns nil if pc could not be expanded.

View File

@@ -7,18 +7,25 @@ package main
import "unsafe"
func init() {
register("CheckPtrAlignment", CheckPtrAlignment)
register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr)
register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr)
register("CheckPtrArithmetic", CheckPtrArithmetic)
register("CheckPtrSize", CheckPtrSize)
register("CheckPtrSmall", CheckPtrSmall)
}
func CheckPtrAlignment() {
func CheckPtrAlignmentNoPtr() {
var x [2]int64
p := unsafe.Pointer(&x[0])
sink2 = (*int64)(unsafe.Pointer(uintptr(p) + 1))
}
func CheckPtrAlignmentPtr() {
var x [2]int64
p := unsafe.Pointer(&x[0])
sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1))
}
func CheckPtrArithmetic() {
var x int
i := uintptr(unsafe.Pointer(&x))

View File

@@ -74,36 +74,26 @@ type timer struct {
// timerNoStatus -> timerWaiting
// anything else -> panic: invalid value
// deltimer:
// timerWaiting -> timerDeleted
// timerWaiting -> timerModifying -> timerDeleted
// timerModifiedEarlier -> timerModifying -> timerDeleted
// timerModifiedLater -> timerDeleted
// timerModifiedLater -> timerModifying -> timerDeleted
// timerNoStatus -> do nothing
// timerDeleted -> do nothing
// timerRemoving -> do nothing
// timerRemoved -> do nothing
// timerRunning -> wait until status changes
// timerMoving -> wait until status changes
// timerModifying -> panic: concurrent deltimer/modtimer calls
// timerModifying -> wait until status changes
// modtimer:
// timerWaiting -> timerModifying -> timerModifiedXX
// timerModifiedXX -> timerModifying -> timerModifiedYY
// timerNoStatus -> timerWaiting
// timerRemoved -> timerWaiting
// timerNoStatus -> timerModifying -> timerWaiting
// timerRemoved -> timerModifying -> timerWaiting
// timerDeleted -> timerModifying -> timerModifiedXX
// timerRunning -> wait until status changes
// timerMoving -> wait until status changes
// timerRemoving -> wait until status changes
// timerDeleted -> panic: concurrent modtimer/deltimer calls
// timerModifying -> panic: concurrent modtimer calls
// resettimer:
// timerNoStatus -> timerWaiting
// timerRemoved -> timerWaiting
// timerDeleted -> timerModifying -> timerModifiedXX
// timerRemoving -> wait until status changes
// timerRunning -> wait until status changes
// timerWaiting -> panic: resettimer called on active timer
// timerMoving -> panic: resettimer called on active timer
// timerModifiedXX -> panic: resettimer called on active timer
// timerModifying -> panic: resettimer called on active timer
// timerModifying -> wait until status changes
// cleantimers (looks in P's timer heap):
// timerDeleted -> timerRemoving -> timerRemoved
// timerModifiedXX -> timerMoving -> timerWaiting
@@ -251,7 +241,7 @@ func addtimer(t *timer) {
t.when = maxWhen
}
if t.status != timerNoStatus {
badTimer()
throw("addtimer called with initialized timer")
}
t.status = timerWaiting
@@ -264,11 +254,9 @@ func addInitializedTimer(t *timer) {
pp := getg().m.p.ptr()
lock(&pp.timersLock)
ok := cleantimers(pp) && doaddtimer(pp, t)
cleantimers(pp)
doaddtimer(pp, t)
unlock(&pp.timersLock)
if !ok {
badTimer()
}
wakeNetPoller(when)
}
@@ -276,7 +264,7 @@ func addInitializedTimer(t *timer) {
// doaddtimer adds t to the current P's heap.
// It reports whether it saw no problems due to races.
// The caller must have locked the timers for pp.
func doaddtimer(pp *p, t *timer) bool {
func doaddtimer(pp *p, t *timer) {
// Timers rely on the network poller, so make sure the poller
// has started.
if netpollInited == 0 {
@@ -289,12 +277,11 @@ func doaddtimer(pp *p, t *timer) bool {
t.pp.set(pp)
i := len(pp.timers)
pp.timers = append(pp.timers, t)
ok := siftupTimer(pp.timers, i)
siftupTimer(pp.timers, i)
if t == pp.timers[0] {
atomic.Store64(&pp.timer0When, uint64(t.when))
}
atomic.Xadd(&pp.numTimers, 1)
return ok
}
// deltimer deletes the timer t. It may be on some other P, so we can't
@@ -305,15 +292,23 @@ func deltimer(t *timer) bool {
for {
switch s := atomic.Load(&t.status); s {
case timerWaiting, timerModifiedLater:
tpp := t.pp.ptr()
if atomic.Cas(&t.status, s, timerDeleted) {
if atomic.Cas(&t.status, s, timerModifying) {
// Must fetch t.pp before changing status,
// as cleantimers in another goroutine
// can clear t.pp of a timerDeleted timer.
tpp := t.pp.ptr()
if !atomic.Cas(&t.status, timerModifying, timerDeleted) {
badTimer()
}
atomic.Xadd(&tpp.deletedTimers, 1)
// Timer was not yet run.
return true
}
case timerModifiedEarlier:
tpp := t.pp.ptr()
if atomic.Cas(&t.status, s, timerModifying) {
// Must fetch t.pp before setting status
// to timerDeleted.
tpp := t.pp.ptr()
atomic.Xadd(&tpp.adjustTimers, -1)
if !atomic.Cas(&t.status, timerModifying, timerDeleted) {
badTimer()
@@ -335,7 +330,8 @@ func deltimer(t *timer) bool {
return false
case timerModifying:
// Simultaneous calls to deltimer and modtimer.
badTimer()
// Wait for the other call to complete.
osyield()
default:
badTimer()
}
@@ -346,7 +342,7 @@ func deltimer(t *timer) bool {
// We are locked on the P when this is called.
// It reports whether it saw no problems due to races.
// The caller must have locked the timers for pp.
func dodeltimer(pp *p, i int) bool {
func dodeltimer(pp *p, i int) {
if t := pp.timers[i]; t.pp.ptr() != pp {
throw("dodeltimer: wrong P")
} else {
@@ -358,29 +354,23 @@ func dodeltimer(pp *p, i int) bool {
}
pp.timers[last] = nil
pp.timers = pp.timers[:last]
ok := true
if i != last {
// Moving to i may have moved the last timer to a new parent,
// so sift up to preserve the heap guarantee.
if !siftupTimer(pp.timers, i) {
ok = false
}
if !siftdownTimer(pp.timers, i) {
ok = false
}
siftupTimer(pp.timers, i)
siftdownTimer(pp.timers, i)
}
if i == 0 {
updateTimer0When(pp)
}
atomic.Xadd(&pp.numTimers, -1)
return ok
}
// dodeltimer0 removes timer 0 from the current P's heap.
// We are locked on the P when this is called.
// It reports whether it saw no problems due to races.
// The caller must have locked the timers for pp.
func dodeltimer0(pp *p) bool {
func dodeltimer0(pp *p) {
if t := pp.timers[0]; t.pp.ptr() != pp {
throw("dodeltimer0: wrong P")
} else {
@@ -392,13 +382,11 @@ func dodeltimer0(pp *p) bool {
}
pp.timers[last] = nil
pp.timers = pp.timers[:last]
ok := true
if last > 0 {
ok = siftdownTimer(pp.timers, 0)
siftdownTimer(pp.timers, 0)
}
updateTimer0When(pp)
atomic.Xadd(&pp.numTimers, -1)
return ok
}
// modtimer modifies an existing timer.
@@ -420,20 +408,23 @@ loop:
case timerNoStatus, timerRemoved:
// Timer was already run and t is no longer in a heap.
// Act like addtimer.
if atomic.Cas(&t.status, status, timerWaiting) {
if atomic.Cas(&t.status, status, timerModifying) {
wasRemoved = true
break loop
}
case timerDeleted:
if atomic.Cas(&t.status, status, timerModifying) {
atomic.Xadd(&t.pp.ptr().deletedTimers, -1)
break loop
}
case timerRunning, timerRemoving, timerMoving:
// The timer is being run or moved, by a different P.
// Wait for it to complete.
osyield()
case timerDeleted:
// Simultaneous calls to modtimer and deltimer.
badTimer()
case timerModifying:
// Multiple simultaneous calls to modtimer.
badTimer()
// Wait for the other call to complete.
osyield()
default:
badTimer()
}
@@ -447,6 +438,9 @@ loop:
if wasRemoved {
t.when = when
addInitializedTimer(t)
if !atomic.Cas(&t.status, timerModifying, timerWaiting) {
badTimer()
}
} else {
// The timer is in some other P's heap, so we can't change
// the when field. If we did, the other P's heap would
@@ -463,7 +457,6 @@ loop:
// Update the adjustTimers field. Subtract one if we
// are removing a timerModifiedEarlier, add one if we
// are adding a timerModifiedEarlier.
tpp := t.pp.ptr()
adjust := int32(0)
if status == timerModifiedEarlier {
adjust--
@@ -472,7 +465,7 @@ loop:
adjust++
}
if adjust != 0 {
atomic.Xadd(&tpp.adjustTimers, adjust)
atomic.Xadd(&t.pp.ptr().adjustTimers, adjust)
}
// Set the new status of the timer.
@@ -487,67 +480,22 @@ loop:
}
}
// resettimer resets an existing inactive timer to turn it into an active timer,
// with a new time for when the timer should fire.
// resettimer resets the time when a timer should fire.
// If used for an inactive timer, the timer will become active.
// This should be called instead of addtimer if the timer value has been,
// or may have been, used previously.
func resettimer(t *timer, when int64) {
if when < 0 {
when = maxWhen
}
for {
switch s := atomic.Load(&t.status); s {
case timerNoStatus, timerRemoved:
if atomic.Cas(&t.status, s, timerWaiting) {
t.when = when
addInitializedTimer(t)
return
}
case timerDeleted:
tpp := t.pp.ptr()
if atomic.Cas(&t.status, s, timerModifying) {
t.nextwhen = when
newStatus := uint32(timerModifiedLater)
if when < t.when {
newStatus = timerModifiedEarlier
atomic.Xadd(&t.pp.ptr().adjustTimers, 1)
}
if !atomic.Cas(&t.status, timerModifying, newStatus) {
badTimer()
}
atomic.Xadd(&tpp.deletedTimers, -1)
if newStatus == timerModifiedEarlier {
wakeNetPoller(when)
}
return
}
case timerRemoving:
// Wait for the removal to complete.
osyield()
case timerRunning:
// Even though the timer should not be active,
// we can see timerRunning if the timer function
// permits some other goroutine to call resettimer.
// Wait until the run is complete.
osyield()
case timerWaiting, timerModifying, timerModifiedEarlier, timerModifiedLater, timerMoving:
// Called resettimer on active timer.
badTimer()
default:
badTimer()
}
}
modtimer(t, when, t.period, t.f, t.arg, t.seq)
}
// cleantimers cleans up the head of the timer queue. This speeds up
// programs that create and delete timers; leaving them in the heap
// slows down addtimer. Reports whether no timer problems were found.
// The caller must have locked the timers for pp.
func cleantimers(pp *p) bool {
func cleantimers(pp *p) {
for {
if len(pp.timers) == 0 {
return true
return
}
t := pp.timers[0]
if t.pp.ptr() != pp {
@@ -558,11 +506,9 @@ func cleantimers(pp *p) bool {
if !atomic.Cas(&t.status, s, timerRemoving) {
continue
}
if !dodeltimer0(pp) {
return false
}
dodeltimer0(pp)
if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
return false
badTimer()
}
atomic.Xadd(&pp.deletedTimers, -1)
case timerModifiedEarlier, timerModifiedLater:
@@ -572,21 +518,17 @@ func cleantimers(pp *p) bool {
// Now we can change the when field.
t.when = t.nextwhen
// Move t to the right position.
if !dodeltimer0(pp) {
return false
}
if !doaddtimer(pp, t) {
return false
}
dodeltimer0(pp)
doaddtimer(pp, t)
if s == timerModifiedEarlier {
atomic.Xadd(&pp.adjustTimers, -1)
}
if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
return false
badTimer()
}
default:
// Head of timers does not need adjustment.
return true
return
}
}
}
@@ -602,9 +544,7 @@ func moveTimers(pp *p, timers []*timer) {
switch s := atomic.Load(&t.status); s {
case timerWaiting:
t.pp = 0
if !doaddtimer(pp, t) {
badTimer()
}
doaddtimer(pp, t)
break loop
case timerModifiedEarlier, timerModifiedLater:
if !atomic.Cas(&t.status, s, timerMoving) {
@@ -612,9 +552,7 @@ func moveTimers(pp *p, timers []*timer) {
}
t.when = t.nextwhen
t.pp = 0
if !doaddtimer(pp, t) {
badTimer()
}
doaddtimer(pp, t)
if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
badTimer()
}
@@ -668,9 +606,7 @@ loop:
switch s := atomic.Load(&t.status); s {
case timerDeleted:
if atomic.Cas(&t.status, s, timerRemoving) {
if !dodeltimer(pp, i) {
badTimer()
}
dodeltimer(pp, i)
if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
badTimer()
}
@@ -686,9 +622,7 @@ loop:
// We don't add it back yet because the
// heap manipulation could cause our
// loop to skip some other timer.
if !dodeltimer(pp, i) {
badTimer()
}
dodeltimer(pp, i)
moved = append(moved, t)
if s == timerModifiedEarlier {
if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 {
@@ -724,9 +658,7 @@ loop:
// back to the timer heap.
func addAdjustedTimers(pp *p, moved []*timer) {
for _, t := range moved {
if !doaddtimer(pp, t) {
badTimer()
}
doaddtimer(pp, t)
if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
badTimer()
}
@@ -780,9 +712,7 @@ func runtimer(pp *p, now int64) int64 {
if !atomic.Cas(&t.status, s, timerRemoving) {
continue
}
if !dodeltimer0(pp) {
badTimer()
}
dodeltimer0(pp)
if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
badTimer()
}
@@ -796,12 +726,8 @@ func runtimer(pp *p, now int64) int64 {
continue
}
t.when = t.nextwhen
if !dodeltimer0(pp) {
badTimer()
}
if !doaddtimer(pp, t) {
badTimer()
}
dodeltimer0(pp)
doaddtimer(pp, t)
if s == timerModifiedEarlier {
atomic.Xadd(&pp.adjustTimers, -1)
}
@@ -847,18 +773,14 @@ func runOneTimer(pp *p, t *timer, now int64) {
// Leave in heap but adjust next time to fire.
delta := t.when - now
t.when += t.period * (1 + -delta/t.period)
if !siftdownTimer(pp.timers, 0) {
badTimer()
}
siftdownTimer(pp.timers, 0)
if !atomic.Cas(&t.status, timerRunning, timerWaiting) {
badTimer()
}
updateTimer0When(pp)
} else {
// Remove from heap.
if !dodeltimer0(pp) {
badTimer()
}
dodeltimer0(pp)
if !atomic.Cas(&t.status, timerRunning, timerNoStatus) {
badTimer()
}
@@ -1076,9 +998,9 @@ func timeSleepUntil() (int64, *p) {
// "panic holding locks" message. Instead, we panic while not
// holding a lock.
func siftupTimer(t []*timer, i int) bool {
func siftupTimer(t []*timer, i int) {
if i >= len(t) {
return false
badTimer()
}
when := t[i].when
tmp := t[i]
@@ -1093,13 +1015,12 @@ func siftupTimer(t []*timer, i int) bool {
if tmp != t[i] {
t[i] = tmp
}
return true
}
func siftdownTimer(t []*timer, i int) bool {
func siftdownTimer(t []*timer, i int) {
n := len(t)
if i >= n {
return false
badTimer()
}
when := t[i].when
tmp := t[i]
@@ -1134,7 +1055,6 @@ func siftdownTimer(t []*timer, i int) bool {
if tmp != t[i] {
t[i] = tmp
}
return true
}
// badTimer is called if the timer data structures have been corrupted,
@@ -1142,5 +1062,5 @@ func siftdownTimer(t []*timer, i int) bool {
// panicing due to invalid slice access while holding locks.
// See issue #25686.
func badTimer() {
panic(errorString("racy use of timers"))
throw("timer data corruption")
}

View File

@@ -9,7 +9,6 @@ import (
"encoding/gob"
"encoding/json"
"fmt"
"internal/race"
"math/big"
"math/rand"
"os"
@@ -1393,23 +1392,11 @@ func TestReadFileLimit(t *testing.T) {
}
// Issue 25686: hard crash on concurrent timer access.
// Issue 37400: panic with "racy use of timers"
// This test deliberately invokes a race condition.
// We are testing that we don't crash with "fatal error: panic holding locks".
// We are testing that we don't crash with "fatal error: panic holding locks",
// and that we also don't panic.
func TestConcurrentTimerReset(t *testing.T) {
if race.Enabled {
t.Skip("skipping test under race detector")
}
// We expect this code to panic rather than crash.
// Don't worry if it doesn't panic.
catch := func(i int) {
if e := recover(); e != nil {
t.Logf("panic in goroutine %d, as expected, with %q", i, e)
} else {
t.Logf("no panic in goroutine %d", i)
}
}
const goroutines = 8
const tries = 1000
var wg sync.WaitGroup
@@ -1418,7 +1405,6 @@ func TestConcurrentTimerReset(t *testing.T) {
for i := 0; i < goroutines; i++ {
go func(i int) {
defer wg.Done()
defer catch(i)
for j := 0; j < tries; j++ {
timer.Reset(Hour + Duration(i*j))
}
@@ -1426,3 +1412,25 @@ func TestConcurrentTimerReset(t *testing.T) {
}
wg.Wait()
}
// Issue 37400: panic with "racy use of timers".
func TestConcurrentTimerResetStop(t *testing.T) {
const goroutines = 8
const tries = 1000
var wg sync.WaitGroup
wg.Add(goroutines * 2)
timer := NewTimer(Hour)
for i := 0; i < goroutines; i++ {
go func(i int) {
defer wg.Done()
for j := 0; j < tries; j++ {
timer.Reset(Hour + Duration(i*j))
}
}(i)
go func(i int) {
defer wg.Done()
timer.Stop()
}(i)
}
wg.Wait()
}

View File

@@ -0,0 +1,32 @@
// run
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "reflect"
// complicated enough to require a compile-generated hash function
type K struct {
a, b int32 // these get merged by the compiler into a single field, something typehash doesn't do
c float64
}
func main() {
k := K{a: 1, b: 2, c: 3}
// Make a reflect map.
m := reflect.MakeMap(reflect.MapOf(reflect.TypeOf(K{}), reflect.TypeOf(true)))
m.SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(true))
// The binary must not contain the type map[K]bool anywhere, or reflect.MapOf
// will use that type instead of making a new one. So use an equivalent named type.
type M map[K]bool
var x M
reflect.ValueOf(&x).Elem().Set(m)
if !x[k] {
panic("key not found")
}
}