diff options
-rw-r--r-- | .hgignore | 58 | ||||
-rw-r--r-- | .hgtags | 138 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | doc/contribute.html | 70 | ||||
-rw-r--r-- | doc/devel/release.html | 7 | ||||
-rw-r--r-- | doc/install-source.html | 61 | ||||
-rw-r--r-- | src/cmd/dist/build.c | 100 | ||||
-rw-r--r-- | src/cmd/gc/reflect.c | 30 | ||||
-rw-r--r-- | src/cmd/go/get.go | 2 | ||||
-rw-r--r-- | src/cmd/ld/dwarf.c | 15 | ||||
-rw-r--r-- | src/cmd/ld/ldelf.c | 5 | ||||
-rw-r--r-- | src/reflect/type.go | 31 | ||||
-rw-r--r-- | src/runtime/cgo/gcc_openbsd_386.c | 40 | ||||
-rw-r--r-- | src/runtime/cgo/gcc_openbsd_amd64.c | 40 | ||||
-rw-r--r-- | src/runtime/crash_cgo_test.go | 68 | ||||
-rw-r--r-- | src/runtime/defs_windows.go | 1 | ||||
-rw-r--r-- | src/runtime/hashmap.go | 35 | ||||
-rw-r--r-- | src/runtime/hashmap_fast.go | 12 | ||||
-rw-r--r-- | src/runtime/mprof.go | 14 | ||||
-rw-r--r-- | src/runtime/os_plan9.go | 2 | ||||
-rw-r--r-- | src/runtime/sigqueue.go | 9 | ||||
-rw-r--r-- | src/runtime/syscall_windows.go | 2 | ||||
-rw-r--r-- | src/syscall/route_openbsd.go | 6 | ||||
-rw-r--r-- | test/fixedbugs/issue9321.go | 37 |
24 files changed, 579 insertions, 206 deletions
diff --git a/.hgignore b/.hgignore new file mode 100644 index 000000000..007116113 --- /dev/null +++ b/.hgignore @@ -0,0 +1,58 @@ +syntax:glob +.DS_Store +.git +.gitignore +*.[568ao] +*.a[568o] +*.so +*.pyc +._* +.nfs.* +[568a].out +*~ +*.orig +*.rej +*.exe +.*.swp +core +*.cgo*.go +*.cgo*.c +_cgo_* +_obj +_test +_testmain.go +build.out +test.out +doc/articles/wiki/*.bin +include/plan9/libc_plan9.h +misc/cgo/life/run.out +misc/cgo/stdio/run.out +misc/cgo/testso/main +misc/dashboard/builder/builder +src/cmd/?a/y.output +src/liblink/anames?.c +src/cmd/cc/y.output +src/cmd/cgo/zdefaultcc.go +src/cmd/dist/dist.dSYM +src/cmd/gc/mkbuiltin1 +src/cmd/gc/opnames.h +src/cmd/gc/y.output +src/cmd/go/zdefaultcc.go +src/go/doc/headscan +src/runtime/mkversion +src/runtime/z* +src/unicode/maketables +src/*.*/ +test/pass.out +test/run.out +test/times.out +test/garbage/*.out +goinstall.log +last-change +VERSION.cache + +syntax:regexp +^bin/ +^pkg/ +^src/cmd/(.*)/6?\1$ +^.*/core.[0-9]*$ diff --git a/.hgtags b/.hgtags new file mode 100644 index 000000000..edd2163f7 --- /dev/null +++ b/.hgtags @@ -0,0 +1,138 @@ +1f0a01c93d305f1ab636c68b67346659c5b957f7 weekly.2009-11-06 +64e703cb307da550861fe740ff70a482a2c14819 weekly.2009-11-10 +b51fd2d6c16034480f26c96ba32a11c598e4638e weekly.2009-11-10.1 +cb140bac9ab0fd9f734ee443cea9ebadc9c99737 weekly.2009-11-12 +d1b75410b793309532352a6fb6b44453f052f3f4 weekly.2009-11-17 +e205103b02e7393d4719df5faac2dac808234d3f weekly.2009-12-07 +3a47d2e3882bb12129de05382a2c131bb0c00964 weekly.2009-12-09 +a6fcf4303b0a92cce4011556b1c96044252d93af weekly.2009-12-22 +3887d4d81bca78b63d620985d93f1cc06c063871 weekly.2010-01-05 +40dd722155f6d0c83fa572c1a5abf7c6ff35049f weekly.2010-01-13 +0a2770db06efe92b08b5c6f30e14b7e8db012538 weekly.2010-01-27 +db4262ce882d8445764312d41547ee8f11a7f7a9 weekly.2010-02-04 +53fec18b83e2b93baafba4733b59bb86b8c1988e weekly.2010-02-17 +4a0661b86e50eae734dbe43ed1312c4a0304676b weekly.2010-02-23 +a215d03e7ee1013b2abe3f1e2c84457ec51c68e4 weekly.2010-03-04 +194d473264c1a015803d07bed200e0c312aca43e weekly.2010-03-15 +9482fde11a02ffd57ba0561dc8a4ac338061a3ae weekly.2010-03-22 +57380d620ee6b65eb88da1c52784b62c94d7e72e weekly.2010-03-30 +f98f784927abc56a61501eba0cf225966f2b0142 weekly.2010-04-13 +6cc6c0d85fc3234fc0a5ec0a8777aa9d59d05ae8 weekly.2010-04-27 +17ded5ad443b41ac05924864798f1bd8750da344 weekly.2010-05-04 +a85ad0a640154b5d33626ad8ea15ed17e3828178 weekly.2010-05-27 +f776656df34c009f2aad142bf7b34a778404acd1 weekly.2010-06-09 +113ec27f29f18825444f6f8a3cdc156c1df28e87 weekly.2010-06-21 +b761e0299e9bf66298778cf170b0f64216e3cf7d weekly.2010-07-01 +5992bf56aa72efcea87d8dff14985fc8fcc68575 weekly.2010-07-14 +db904d88dc0ebf6ee5b55e44088915695c1223ee weekly.2010-07-29 +8884f7b4c7750481ed246c249db47b61fe752c56 weekly.2010-08-04 +07d3a97302be88af68acff34c8a089589da21d18 weekly.2010-08-11 +18926649cda7498b8aa539b3a611abcff548f09f weekly.2010-08-25 +92fcf05736e8565a485adc52da1894270e06ed09 weekly.2010-09-06 +9329773e204fed50ec686ee78cc715b624bf1b1d weekly.2010-09-15 +1eec33c03bceef5d7607ea4636185f7bf773e0e4 weekly.2010-09-22 +c2b8c9f13fb8ad2b56920d9da2928c5314ebf725 weekly.2010-09-29 +7c2e97710bf49cdbe388260958a6674afefb6c0f weekly.2010-10-13 +ca4f9687cec0b9c4732afd57b8c2786c7fe242de weekly.2010-10-13.1 +79997f0e5823ee9d13a34ca9971a9d8811df1c4a weekly.2010-10-20 +4d5b0816392116d3a3452bb275b6dab6c6456278 weekly.2010-10-27 +c627e23260c7ddf4a1fcda6ef3197c98fa22551d weekly.2010-11-02 +a7800e20064a39585aa3ee339c2b7454ae1ce6d5 weekly.2010-11-10 +c5287468fcff0f8a7bb9ffaece2a4863e7e5d83e weekly.2010-11-23 +f7e692dc29b02fba8e5d59b967880a347b53607c weekly.2010-12-02 +56e39c466cc1c49b587eb56dc2166d61151637df weekly.2010-12-08 +26f4898dc1ca18bb77f9968aca23773637e34f0d weekly.2010-12-15 +61b2c52b0d2246430395f2869d7b34e565333cf5 weekly.2010-12-15.1 +51c777dbccb9f537ebffb99244f521c05bf65df6 weekly.2010-12-22 +8eeee945e358f19405e81792db0e16a1cad14bc0 weekly.2011-01-06 +514c7ba501a1dd74d69ea2d0a2b4116802ada2b5 weekly.2011-01-12 +72f9cb714f08b98c6a65ab2f2256fad6bb16967a weekly.2011-01-19 +d8ba80011a986470a54e5262ec125105aa4adc34 weekly.2011-01-20 +5b98b59dd37292e36afb24babb2d22758928e13d weekly.2011-02-01 +867d37fb41a4d96ab7a6202fd6ad54c345494051 weekly.2011-02-01.1 +b2be017f91348d5f8cbaf42f77a99fc905044b59 weekly.2011-02-15 +322350d6fdbf11d9c404d6fc766349d824031339 weekly.2011-02-24 +21848430d60167817ca965c813a2118068ca660f weekly.2011-03-07 +c5c62aeb6267e124cf05f9622e28dbd0dc6b971d weekly.2011-03-07.1 +c5c62aeb6267e124cf05f9622e28dbd0dc6b971d release.r56 +3b4e9c85b643a35860805718323b05186dd7f235 weekly.2011-03-15 +b84e614e25161f626a6102813c41a80a15e3a625 weekly.2011-03-28 +cd89452cfea3d125aaf75a1ec8004e2f6a868d38 weekly.2011-04-04 +d6903b7fbff40c13ee7ea3177c0ae54c7f89d2e6 weekly.2011-04-13 +2f0fa51fa2da6ab50fcebba526326153da8ed999 weekly.2011-04-27 +8493bb64e5592bd20c0e60e78e7f8052c1276fcf release.r57 +95d2ce135523c96c4cea049af94ce76dd8c7d981 release.r57.1 +c98449d685d2b6aa1df9bfd2e1cce9307efb6e00 weekly.2011-05-22 +3418f22c39eb8299053ae681199ee90f8cd29c6d weekly.2011-06-02 +c81944152e973a917797679055b8fcdc70fbc802 weekly.2011-06-09 +9d7967223815ef6415ff01aa0fe6ad38cdbc7810 release.r57.2 +dac76f0b1a18a5de5b54a1dc0b231aceaf1c8583 weekly.2011-06-16 +541c445d6c1353fbfa39df7dc4b0eb27558d1fc1 weekly.2011-06-23 +1b38d90eebcddefabb3901c5bb63c7e2b04a6ec5 release.r58 +16bfa562ba767aefd82e598da8b15ee4729e23b0 weekly.2011-07-07 +d292bc7886682d35bb391bf572be28656baee12d release.r58.1 +3c21f37b25a3f7a1726265c5339c8a7b0b329336 weekly.2011-07-19 +bb28251f6da4aca85658582c370c7df89d34efd4 weekly.2011-07-29 +d5785050f61d973fc36775f7bd2e26689529cb3e release.r59 +c17ce5ec06b4bd5cf6e7ff2ceb0a60c2e40e0b17 weekly.2011-08-10 +6eb2b9dbe489acb57a2bfc1de31ec2239ed94326 weekly.2011-08-17 +c934f6f5fe8b30b4b3210ee3f13669e6e4670c32 weekly.2011-09-01 +c77997547d546c36c7b969586a36de7ceda74e33 weekly.2011-09-07 +b0819469a6df6029a27192fe7b19a73d97404c63 release.r60 +8a09ce0cefc64deab4e6d1ed59a08a53e879bbee weekly.2011-09-16 +fd30c132d1bdeb79f8f111cb721fb1c78b767b27 release.r60.1 +d7322ae4d055a4cf3efaf842d0717a41acd85bac weekly.2011-09-21 +32a5db19629897641b2d488de4d1b998942ef80e release.r60.2 +3bdabf483805fbf0c7ef013fd09bfd6062b9d3f2 weekly.2011-10-06 +c1702f36df0397c19fc333571a771666029aa37e release.r60.3 +acaddf1cea75c059d19b20dbef35b20fb3f38954 release.r58.2 +6d7136d74b656ba6e1194853a9486375005227ef weekly.2011-10-18 +941b8015061a0f6480954821dd589c60dfe35ed1 weekly.2011-10-25 +7c1f789e6efd153951e85e3f28722fc69efc2af2 weekly.2011-10-26 +e69e528f2afc25a8334cfb9359fa4fcdf2a934b6 weekly.2011-11-01 +780c85032b174c9d4b42adf75d82bc85af7d78d1 weekly.2011-11-02 +f4397ad6e87c7ce5feac9b01686f1ebd6cbaac4e weekly.2011-11-08 +2f4482b89a6b5956828872137b6b96636cd904d3 weekly.2011-11-09 +b4a91b6933748db1a7150c06a1b55ad506e52906 weekly.2011-11-18 +80db2da6495a20ddff8305c236825811db8c8665 weekly.2011-12-01 +0beb796b4ef8747af601ed5ea6766d5b1340086b weekly.2011-12-02 +0c39eee85b0d1606b79c8ebcdeb3b67ed5849e39 weekly.2011-12-06 +82fdc445f2ff2c85043446eb84a19cc999dfcb95 weekly.2011-12-14 +4a82689277582a2a60f006e3f158985f2f8d1da3 weekly.2011-12-22 +354b17404643c0f1a710bdc48927dff02f203ae3 weekly.2012-01-15 +9f2be4fbbf690b9562c6e98b91daa0003f0913c7 weekly.2012-01-20 +1107a7d3cb075836387adfab5ce56d1b3e56637d weekly.2012-01-27 +52ba9506bd993663a0a033c2bd68699e25d061ab weekly.2012-02-07 +43cf9b39b6477d3144b0353ee91096e55db6107f weekly.2012-02-14 +96bd78e7d35e892113bdfa1bdc392d3a5f2e644b weekly.2012-02-22 +f4470a54e6dbcdd52d8d404e12e4754adcd2c948 weekly.2012-03-04 +3cdba7b0650c6c906ef3e782654f61701abd7dd2 weekly.2012-03-13 +bce220d0377405146527ab9478867cbc572a6886 weekly.2012-03-22 +dc5e410f0b4c32ab11dc992593a2bcf5f607381b weekly.2012-03-27 +dc5e410f0b4c32ab11dc992593a2bcf5f607381b weekly +920e9d1ffd1f46665dd152aa9cf3c0f17d68dd88 go1 +2ccfd4b451d319941bfe3e08037e1462d3c15093 go1.0.1 +5e806355a9e1491aaab53d3612fed4c550b130c0 go1.0.2 +2d8bc3c94ecb3ec8f70556d5fd237788903c7281 go1.0.3 +35da6063e57f8cefc82ba1ea542c4d9393ea9dfd go1.1rc2 +5a15f0dae37931da46f0356cf4cffe775a061c12 go1.1rc3 +e570c2daeaca10663d36d6dee7f8d1d76e8f7b92 go1.1 +a7bd9a33067b3537351276e0178a045748ad046a go1.1.1 +414057ac1f1fc850957088e4c5e95cdbccd2d594 go1.1.2 +45475ec7eab1c588fc4210b34d5901b15ca1e479 go1.2rc2 +7422495a6bf9d5e84828ee466406293be84f565a go1.2rc3 +94af58f9fd71feda5c316d791ed11aaf015f9e82 go1.2rc4 +b3d5a20b070a92da2458c5788694d1359b353f4a go1.2rc5 +87dea3f5ebe7510998c84dbeeec89382b7d42f9c go1.2 +0ddbdc3c7ce27e66508fe58ab81ff29324786026 go1.2.1 +9c4fdd8369ca4483fbed1cb8e67f02643ca10f79 go1.2.2 +f8b50ad4cac4d4c4ecf48324b4f512f65e82cc1c go1.3beta1 +9e1652c32289c164126b6171f024afad5665fc9e go1.3beta2 +9d5451df4e53acc58a848005b7ec3a24c4b6050c go1.3rc1 +3f66a43d5180052e2e1e38d979d1aa5ad05b21f9 go1.3rc2 +9895f9e36435468d503eaa74ee217f28d5e28dd4 go1.3 +073fc578434bf3e1e22749b559d273c8da728ebb go1.3.1 +85518b1d6f8d6e16133b9ed2c9db6807522d37de go1.3.2 +f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 go1.3.3 +f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 release +1fdfd7dfaedb1b7702141617e621ab7328a236a1 go1.4beta1 @@ -1 +1 @@ -go1.4
\ No newline at end of file +go1.4.1
\ No newline at end of file diff --git a/doc/contribute.html b/doc/contribute.html index ba550d528..63d477462 100644 --- a/doc/contribute.html +++ b/doc/contribute.html @@ -6,19 +6,10 @@ <p> This document explains how to contribute changes to the Go project. -It assumes you have installed Go from source: -<p> - -<pre> -$ git clone https://go.googlesource.com/go -$ cd go/src -$ ./all.bash -</pre> -<!-- -TODO(adg): delete the above, restore the below after we have updated install-source.html +It assumes you have followed the <a href="/doc/install/source">installation instructions</a> and have <a href="code.html">written and tested your code</a>. ---> +</p> <p> (Note that the <code>gccgo</code> frontend lives elsewhere; @@ -77,7 +68,7 @@ Changes to Go must be reviewed before they are submitted, no matter who makes the change. (In exceptional cases, such as fixing a build, the review can follow shortly after submitting.) -A custom git command called <code>git-review</code>, +A custom git command called <code>git-codereview</code>, discussed below, helps manage the code review process through a Google-hosted <a href="https://go-review.googlesource.com/">instance</a> of the code review system called <a href="https://code.google.com/p/gerrit/">Gerrit</a>. @@ -132,53 +123,53 @@ and log in using the same Google Account you used above. That is all that is required. </p> -<h3>Install the git-review command</h3> +<h3>Install the git-codereview command</h3> <p> -Now install the <code>git-review</code> command by running, +Now install the <code>git-codereview</code> command by running, </p> <pre> -go get -u golang.org/x/review/git-review +go get -u golang.org/x/review/git-codereview </pre> <p> -Make sure <code>git-review</code> is installed in your shell path, so that the +Make sure <code>git-codereview</code> is installed in your shell path, so that the <code>git</code> command can find it. Check that </p> <pre> -$ git review help +$ git codereview help </pre> - + <p> prints help text, not an error. </p> <p> -Note to Git aficionados: The <code>git-review</code> command is not required to +Note to Git aficionados: The <code>git-codereview</code> command is not required to upload and manage Gerrit code reviews. For those who prefer plain Git, the text -below gives the Git equivalent of each git-review command. If you do use plain -Git, note that you still need the commit hooks that the git-review command +below gives the Git equivalent of each git-codereview command. If you do use plain +Git, note that you still need the commit hooks that the git-codereview command configures; those hooks add a Gerrit <code>Change-Id</code> line to the commit message and check that all Go source files have been formatted with gofmt. Even if you intend to use plain Git for daily work, install the hooks in a new Git -checkout by running <code>git-review</code> <code>hooks</code>). +checkout by running <code>git-codereview</code> <code>hooks</code>. </p> <h3>Set up git aliases</h3> <p> -The <code>git-review</code> command can be run directly from the shell +The <code>git-codereview</code> command can be run directly from the shell by typing, for instance, </p> <pre> -$ git review sync +$ git codereview sync </pre> <p> -but it is more convenient to set up aliases for <code>git-review</code>'s own +but it is more convenient to set up aliases for <code>git-codereview</code>'s own subcommands, so that the above becomes, </p> @@ -186,8 +177,8 @@ subcommands, so that the above becomes, $ git sync </pre> -</p> -The <code>git-review</code> subcommands have been chosen to be distinct from +<p> +The <code>git-codereview</code> subcommands have been chosen to be distinct from Git's own, so it's safe to do so. </p> @@ -200,24 +191,25 @@ To install them, copy this text into your Git configuration file <pre> [alias] - change = review change - gofmt = review gofmt - mail = review mail - pending = review pending - sync = review sync + change = codereview change + gofmt = codereview gofmt + mail = codereview mail + pending = codereview pending + submit = codereview submit + sync = codereview sync </pre> -<h3>Understanding the git-review command</h3> +<h3>Understanding the git-codereview command</h3> -<p>After installing the <code>git-review</code> command, you can run</p> +<p>After installing the <code>git-codereview</code> command, you can run</p> <pre> -$ git review help +$ git codereview help </pre> <p> to learn more about its commands. -You can also read the <a href="https://godoc.org/golang.org/x/review/git-review">command documentation</a>. +You can also read the <a href="https://godoc.org/golang.org/x/review/git-codereview">command documentation</a>. </p> <h3>Switch to the master branch</h3> @@ -367,7 +359,7 @@ Do not edit or delete it. <p> (In Git terms, <code>git</code> <code>change</code> with no branch name runs <code>git</code> <code>commit</code> <code>--amend</code>.) -</p> +</p> <h3>Mail the change for review</h3> @@ -469,7 +461,7 @@ $ git sync </pre> <p> -(In git terms, git sync runs +(In git terms, <code>git</code> <code>sync</code> runs <code>git</code> <code>pull</code> <code>-r</code>.) </p> @@ -660,7 +652,7 @@ This rigmarole needs to be done only for your first submission. <p>Code that you contribute should use the standard copyright header:</p> <pre> -// Copyright 2014 The Go Authors. All rights reserved. +// Copyright 2015 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. </pre> diff --git a/doc/devel/release.html b/doc/devel/release.html index 5b5d6ab5e..6e69ce70e 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -19,6 +19,13 @@ Go 1.4 is a major release of Go. Read the <a href="/doc/go1.4">Go 1.4 Release Notes</a> for more information. </p> +<h3 id="go1.4.minor">Minor revisions</h3> + +<p> +go1.4.1 (released 2015/01/15) includes bug fixes to the linker and the <code>log</code>, <code>syscall</code>, and <code>runtime</code> packages. +See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.4.1">Go 1.4.1 milestone on our issue tracker</a> for details. +</p> + <h2 id="go1.3">go1.3 (released 2014/06/18)</h2> <p> diff --git a/doc/install-source.html b/doc/install-source.html index f53deb404..7daf360a0 100644 --- a/doc/install-source.html +++ b/doc/install-source.html @@ -81,38 +81,21 @@ The full set of supported combinations is listed in the discussion of <p> The Go tool chain is written in C. To build it, you need a C compiler installed. -Please refer to the <a href="//golang.org/wiki/InstallFromSource#Install_C_tools">InstallFromSource</a> +Please refer to the <a href="//golang.org/wiki/InstallFromSource#install-c-tools">InstallFromSource</a> page on the Go community Wiki for operating system specific instructions. </p> -<h2 id="mercurial">Install Mercurial, if needed</h2> +<h2 id="git">Install Git, if needed</h2> <p> -To perform the next step you must have Mercurial installed. (Check that you -have an <code>hg</code> command.) +To perform the next step you must have Git installed. (Check that you +have a <code>git</code> command before proceeding.) </p> <p> -If you do not have a working Mercurial installation, +If you do not have a working Git installation, follow the instructions on the -<a href="http://mercurial.selenic.com/downloads">Mercurial downloads</a> page. -</p> - -<p> -Mercurial versions 1.7.x and up require the configuration of -<a href="http://mercurial.selenic.com/wiki/CACertificates">Certification Authorities</a> -(CAs). Error messages of the form: -</p> - -<pre> -warning: code.google.com certificate with fingerprint b1:af: ... bc not verified (check hostfingerprints or web.cacerts config setting) -</pre> - -<p> -when using Mercurial indicate that the CAs are missing. -Check your Mercurial version (<code>hg --version</code>) and -<a href="http://mercurial.selenic.com/wiki/CACertificates#Configuration_of_HTTPS_certificate_authorities">configure the CAs</a> -if necessary. +<a href="http://git-scm.com/downloads">Git downloads</a> page. </p> @@ -121,22 +104,24 @@ if necessary. <p>Go will install to a directory named <code>go</code>. Change to the directory that will be its parent and make sure the <code>go</code> directory does not exist. -Then check out the repository:</p> +Then clone the repository and check out the latest release tag:</p> <pre> -$ hg clone -u release https://code.google.com/p/go +$ git clone https://go.googlesource.com/go +$ cd go +$ git checkout go1.4.1 </pre> -<h2 id="head">(Optional) Switch to the default branch</h2> +<h2 id="head">(Optional) Switch to the master branch</h2> <p>If you intend to modify the go source code, and <a href="/doc/contribute.html">contribute your changes</a> to the project, then move your repository -off the release branch, and onto the default (development) branch. +off the release branch, and onto the master (development) branch. Otherwise, skip this step.</p> <pre> -$ hg update default +$ git checkout master </pre> <h2 id="install">Install Go</h2> @@ -259,7 +244,7 @@ $ go get golang.org/x/tools/cmd/godoc <p> To install these tools, the <code>go</code> <code>get</code> command requires -that <a href="#mercurial">Mercurial</a> be installed locally. +that <a href="#git">Git</a> be installed locally. </p> <p> @@ -292,22 +277,18 @@ that receives a message summarizing each checkin to the Go repository. </p> <p> -Bugs can be reported using the <a href="//code.google.com/p/go/issues/list">Go issue tracker</a>. +Bugs can be reported using the <a href="//golang.org/issue/new">Go issue tracker</a>. </p> <h2 id="releases">Keeping up with releases</h2> <p> -The Go project maintains a stable tag in its Mercurial repository: -<code>release</code>. -</p> - -<p> -The <code>release</code> tag refers to the current stable release of Go. -Most Go users should use this version. New releases are announced on the +New releases are announced on the <a href="//groups.google.com/group/golang-announce">golang-announce</a> mailing list. +Each announcement mentions the latest release tag, for instance, +<code>go1.4</code>. </p> <p> @@ -316,11 +297,13 @@ To update an existing tree to the latest release, you can run: <pre> $ cd go/src -$ hg pull -$ hg update release +$ git fetch +$ git checkout <i><tag></i> $ ./all.bash </pre> +Where <code><tag></code> is the version string of the release. + <h2 id="environment">Optional environment variables</h2> diff --git a/src/cmd/dist/build.c b/src/cmd/dist/build.c index d638ae4eb..b6c61b491 100644 --- a/src/cmd/dist/build.c +++ b/src/cmd/dist/build.c @@ -235,24 +235,65 @@ chomp(Buf *b) b->len--; } +static char* +branchtag(char *branch, bool *precise) +{ + char *tag, *p, *q; + int i; + Buf b, arg; + Vec tags; + + binit(&b); + binit(&arg); + vinit(&tags); + + bprintf(&arg, "master..%s", branch); + run(&b, goroot, CheckExit, "git", "log", "--decorate=full", "--format=format:%d", bstr(&arg), nil); + + splitlines(&tags, bstr(&b)); + tag = branch; + for(i=0; i < tags.len; i++) { + // Each line is either blank, or looks like + // (tag: refs/tags/go1.4rc2, refs/remotes/origin/release-branch.go1.4, refs/heads/release-branch.go1.4) + // We need to find an element starting with refs/tags/. + p = xstrstr(tags.p[i], " refs/tags/"); + if(p == nil) + continue; + p += xstrlen(" refs/tags/"); + // The tag name ends at a comma or paren (prefer the first). + q = xstrstr(p, ","); + if(q == nil) + q = xstrstr(p, ")"); + if(q == nil) + continue; // malformed line; ignore it + *q = '\0'; + tag = xstrdup(p); + if(i == 0) + *precise = 1; // tag denotes HEAD + break; + } + + bfree(&b); + bfree(&arg); + vfree(&tags); + return tag; +} // findgoversion determines the Go version to use in the version string. static char* findgoversion(void) { - char *tag, *rev, *p; - int i, nrev; + char *tag, *p; + bool precise; Buf b, path, bmore, branch; - Vec tags; binit(&b); binit(&path); binit(&bmore); binit(&branch); - vinit(&tags); // The $GOROOT/VERSION file takes priority, for distributions - // without the Mercurial repo. + // without the source repo. bpathf(&path, "%s/VERSION", goroot); if(isfile(bstr(&path))) { readfile(&b, bstr(&path)); @@ -266,7 +307,7 @@ findgoversion(void) } // The $GOROOT/VERSION.cache file is a cache to avoid invoking - // hg every time we run this command. Unlike VERSION, it gets + // git every time we run this command. Unlike VERSION, it gets // deleted by the clean command. bpathf(&path, "%s/VERSION.cache", goroot); if(isfile(bstr(&path))) { @@ -275,49 +316,27 @@ findgoversion(void) goto done; } - // Otherwise, use Mercurial. + // Otherwise, use Git. // What is the current branch? - run(&branch, goroot, CheckExit, "hg", "identify", "-b", nil); + run(&branch, goroot, CheckExit, "git", "rev-parse", "--abbrev-ref", "HEAD", nil); chomp(&branch); // What are the tags along the current branch? tag = "devel"; - rev = "."; - run(&b, goroot, CheckExit, "hg", "log", "-b", bstr(&branch), "-r", ".:0", "--template", "{tags} + ", nil); - splitfields(&tags, bstr(&b)); - nrev = 0; - for(i=0; i<tags.len; i++) { - p = tags.p[i]; - if(streq(p, "+")) - nrev++; - // Only show the beta tag for the exact revision. - if(hasprefix(p, "go") && (!contains(p, "beta") || nrev == 0)) { - tag = xstrdup(p); - // If this tag matches the current checkout - // exactly (no "+" yet), don't show extra - // revision information. - if(nrev == 0) - rev = ""; - break; - } - } + precise = 0; - if(tag[0] == '\0') { - // Did not find a tag; use branch name. - bprintf(&b, "branch.%s", bstr(&branch)); - tag = btake(&b); - } - - if(rev[0]) { - // Tag is before the revision we're building. - // Add extra information. - run(&bmore, goroot, CheckExit, "hg", "log", "--template", " +{node|short} {date|date}", "-r", rev, nil); - chomp(&bmore); - } + // If we're on a release branch, use the closest matching tag + // that is on the release branch (and not on the master branch). + if(hasprefix(bstr(&branch), "release-branch.")) + tag = branchtag(bstr(&branch), &precise); bprintf(&b, "%s", tag); - if(bmore.len > 0) + if(!precise) { + // Tag does not point at HEAD; add hash and date to version. + run(&bmore, goroot, CheckExit, "git", "log", "-n", "1", "--format=format: +%h %cd", "HEAD", nil); + chomp(&bmore); bwriteb(&b, &bmore); + } // Cache version. writefile(&b, bstr(&path), 0); @@ -330,7 +349,6 @@ done: bfree(&path); bfree(&bmore); bfree(&branch); - vfree(&tags); return p; } diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c index b2ff2fbc5..8788a678b 100644 --- a/src/cmd/gc/reflect.c +++ b/src/cmd/gc/reflect.c @@ -143,18 +143,6 @@ mapbucket(Type *t) // We don't need to encode it as GC doesn't care about it. offset = BUCKETSIZE * 1; - overflowfield = typ(TFIELD); - overflowfield->type = ptrto(bucket); - overflowfield->width = offset; // "width" is offset in structure - overflowfield->sym = mal(sizeof(Sym)); // not important but needs to be set to give this type a name - overflowfield->sym->name = "overflow"; - offset += widthptr; - - // The keys are padded to the native integer alignment. - // This is usually the same as widthptr; the exception (as usual) is nacl/amd64. - if(widthreg > widthptr) - offset += widthreg - widthptr; - keysfield = typ(TFIELD); keysfield->type = typ(TARRAY); keysfield->type->type = keytype; @@ -175,11 +163,23 @@ mapbucket(Type *t) valuesfield->sym->name = "values"; offset += BUCKETSIZE * valtype->width; + overflowfield = typ(TFIELD); + overflowfield->type = ptrto(bucket); + overflowfield->width = offset; // "width" is offset in structure + overflowfield->sym = mal(sizeof(Sym)); // not important but needs to be set to give this type a name + overflowfield->sym->name = "overflow"; + offset += widthptr; + + // Pad to the native integer alignment. + // This is usually the same as widthptr; the exception (as usual) is nacl/amd64. + if(widthreg > widthptr) + offset += widthreg - widthptr; + // link up fields - bucket->type = overflowfield; - overflowfield->down = keysfield; + bucket->type = keysfield; keysfield->down = valuesfield; - valuesfield->down = T; + valuesfield->down = overflowfield; + overflowfield->down = T; bucket->width = offset; bucket->local = t->local; diff --git a/src/cmd/go/get.go b/src/cmd/go/get.go index 86e169761..50e0ca93b 100644 --- a/src/cmd/go/get.go +++ b/src/cmd/go/get.go @@ -290,7 +290,7 @@ func downloadPackage(p *Package) error { } } if remote != repo { - return fmt.Errorf("%s is from %s, should be from %s", dir, remote, repo) + return fmt.Errorf("%s is a custom import path for %s, but %s is checked out from %s", rr.root, repo, dir, remote) } } } diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c index a3ba52325..dfe515c3c 100644 --- a/src/cmd/ld/dwarf.c +++ b/src/cmd/ld/dwarf.c @@ -1281,12 +1281,19 @@ synthesizemaptypes(DWDie *die) fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys"); newrefattr(fld, DW_AT_type, dwhk); - newmemberoffsetattr(fld, BucketSize + PtrSize); + newmemberoffsetattr(fld, BucketSize); fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values"); newrefattr(fld, DW_AT_type, dwhv); - newmemberoffsetattr(fld, BucketSize + PtrSize + BucketSize * keysize); - newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + PtrSize + BucketSize * keysize + BucketSize * valsize, 0); - substitutetype(dwhb, "overflow", defptrto(dwhb)); + newmemberoffsetattr(fld, BucketSize + BucketSize * keysize); + fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow"); + newrefattr(fld, DW_AT_type, defptrto(dwhb)); + newmemberoffsetattr(fld, BucketSize + BucketSize * (keysize + valsize)); + if(RegSize > PtrSize) { + fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad"); + newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")); + newmemberoffsetattr(fld, BucketSize + BucketSize * (keysize + valsize) + PtrSize); + } + newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + BucketSize * keysize + BucketSize * valsize + RegSize, 0); // Construct hash<K,V> dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c index b5d081949..dd5fa0d2a 100644 --- a/src/cmd/ld/ldelf.c +++ b/src/cmd/ld/ldelf.c @@ -539,7 +539,10 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) s->type = SRODATA; break; case ElfSectFlagAlloc + ElfSectFlagWrite: - s->type = SNOPTRDATA; + if(sect->type == ElfSectNobits) + s->type = SNOPTRBSS; + else + s->type = SNOPTRDATA; break; case ElfSectFlagAlloc + ElfSectFlagExec: s->type = STEXT; diff --git a/src/reflect/type.go b/src/reflect/type.go index c0ddfcad0..6fd6894cf 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -1498,8 +1498,9 @@ func MapOf(key, elem Type) Type { // gcProg is a helper type for generatation of GC pointer info. type gcProg struct { - gc []byte - size uintptr // size of type in bytes + gc []byte + size uintptr // size of type in bytes + hasPtr bool } func (gc *gcProg) append(v byte) { @@ -1560,11 +1561,14 @@ func (gc *gcProg) appendWord(v byte) { gc.gc[nptr/2] &= ^(3 << ((nptr%2)*4 + 2)) gc.gc[nptr/2] |= v << ((nptr%2)*4 + 2) gc.size += ptrsize + if v == bitsPointer { + gc.hasPtr = true + } } -func (gc *gcProg) finalize() unsafe.Pointer { +func (gc *gcProg) finalize() (unsafe.Pointer, bool) { if gc.size == 0 { - return nil + return nil, false } ptrsize := unsafe.Sizeof(uintptr(0)) gc.align(ptrsize) @@ -1579,7 +1583,7 @@ func (gc *gcProg) finalize() unsafe.Pointer { gc.appendWord(extractGCWord(gc.gc, i)) } } - return unsafe.Pointer(&gc.gc[0]) + return unsafe.Pointer(&gc.gc[0]), gc.hasPtr } func extractGCWord(gc []byte, i uintptr) byte { @@ -1624,10 +1628,6 @@ func bucketOf(ktyp, etyp *rtype) *rtype { for i := 0; i < int(bucketSize*unsafe.Sizeof(uint8(0))/ptrsize); i++ { gc.append(bitsScalar) } - gc.append(bitsPointer) // overflow - if runtime.GOARCH == "amd64p32" { - gc.append(bitsScalar) - } // keys for i := 0; i < bucketSize; i++ { gc.appendProg(ktyp) @@ -1636,10 +1636,15 @@ func bucketOf(ktyp, etyp *rtype) *rtype { for i := 0; i < bucketSize; i++ { gc.appendProg(etyp) } + // overflow + gc.append(bitsPointer) + if runtime.GOARCH == "amd64p32" { + gc.append(bitsScalar) + } b := new(rtype) b.size = gc.size - b.gc[0] = gc.finalize() + b.gc[0], _ = gc.finalize() s := "bucket(" + *ktyp.string + "," + *etyp.string + ")" b.string = &s return b @@ -1840,7 +1845,11 @@ func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uin // build dummy rtype holding gc program x := new(rtype) x.size = gc.size - x.gc[0] = gc.finalize() + var hasPtr bool + x.gc[0], hasPtr = gc.finalize() + if !hasPtr { + x.kind |= kindNoPointers + } var s string if rcvr != nil { s = "methodargs(" + *rcvr.string + ")(" + *t.string + ")" diff --git a/src/runtime/cgo/gcc_openbsd_386.c b/src/runtime/cgo/gcc_openbsd_386.c index 582e943f3..c4be9a009 100644 --- a/src/runtime/cgo/gcc_openbsd_386.c +++ b/src/runtime/cgo/gcc_openbsd_386.c @@ -65,12 +65,39 @@ thread_start_wrapper(void *arg) return args.func(args.arg); } +static void init_pthread_wrapper(void) { + void *handle; + + // Locate symbol for the system pthread_create function. + handle = dlopen("libpthread.so", RTLD_LAZY); + if(handle == NULL) { + fprintf(stderr, "runtime/cgo: dlopen failed to load libpthread: %s\n", dlerror()); + abort(); + } + sys_pthread_create = dlsym(handle, "pthread_create"); + if(sys_pthread_create == NULL) { + fprintf(stderr, "runtime/cgo: dlsym failed to find pthread_create: %s\n", dlerror()); + abort(); + } + dlclose(handle); +} + +static pthread_once_t init_pthread_wrapper_once = PTHREAD_ONCE_INIT; + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { struct thread_args *p; + // we must initialize our wrapper in pthread_create, because it is valid to call + // pthread_create in a static constructor, and in fact, our test for issue 9456 + // does just that. + if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) { + fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n"); + abort(); + } + p = malloc(sizeof(*p)); if(p == NULL) { errno = ENOMEM; @@ -87,7 +114,6 @@ x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - void *handle; setg_gcc = setg; pthread_attr_init(&attr); @@ -95,18 +121,10 @@ x_cgo_init(G *g, void (*setg)(void*)) g->stacklo = (uintptr)&attr - size + 4096; pthread_attr_destroy(&attr); - // Locate symbol for the system pthread_create function. - handle = dlopen("libpthread.so", RTLD_LAZY); - if(handle == NULL) { - fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror()); - abort(); - } - sys_pthread_create = dlsym(handle, "pthread_create"); - if(sys_pthread_create == NULL) { - fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror()); + if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) { + fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n"); abort(); } - dlclose(handle); tcb_fixup(1); } diff --git a/src/runtime/cgo/gcc_openbsd_amd64.c b/src/runtime/cgo/gcc_openbsd_amd64.c index 35b359bba..8522cd48c 100644 --- a/src/runtime/cgo/gcc_openbsd_amd64.c +++ b/src/runtime/cgo/gcc_openbsd_amd64.c @@ -65,12 +65,39 @@ thread_start_wrapper(void *arg) return args.func(args.arg); } +static void init_pthread_wrapper(void) { + void *handle; + + // Locate symbol for the system pthread_create function. + handle = dlopen("libpthread.so", RTLD_LAZY); + if(handle == NULL) { + fprintf(stderr, "runtime/cgo: dlopen failed to load libpthread: %s\n", dlerror()); + abort(); + } + sys_pthread_create = dlsym(handle, "pthread_create"); + if(sys_pthread_create == NULL) { + fprintf(stderr, "runtime/cgo: dlsym failed to find pthread_create: %s\n", dlerror()); + abort(); + } + dlclose(handle); +} + +static pthread_once_t init_pthread_wrapper_once = PTHREAD_ONCE_INIT; + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { struct thread_args *p; + // we must initialize our wrapper in pthread_create, because it is valid to call + // pthread_create in a static constructor, and in fact, our test for issue 9456 + // does just that. + if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) { + fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n"); + abort(); + } + p = malloc(sizeof(*p)); if(p == NULL) { errno = ENOMEM; @@ -87,7 +114,6 @@ x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - void *handle; setg_gcc = setg; pthread_attr_init(&attr); @@ -95,18 +121,10 @@ x_cgo_init(G *g, void (*setg)(void*)) g->stacklo = (uintptr)&attr - size + 4096; pthread_attr_destroy(&attr); - // Locate symbol for the system pthread_create function. - handle = dlopen("libpthread.so", RTLD_LAZY); - if(handle == NULL) { - fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror()); - abort(); - } - sys_pthread_create = dlsym(handle, "pthread_create"); - if(sys_pthread_create == NULL) { - fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror()); + if(pthread_once(&init_pthread_wrapper_once, init_pthread_wrapper) != 0) { + fprintf(stderr, "runtime/cgo: failed to initialize pthread_create wrapper\n"); abort(); } - dlclose(handle); tcb_fixup(1); } diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index 972eedc62..29f90fa36 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -7,6 +7,7 @@ package runtime_test import ( + "os/exec" "runtime" "strings" "testing" @@ -50,6 +51,30 @@ func TestCgoExternalThreadPanic(t *testing.T) { } } +func TestCgoExternalThreadSIGPROF(t *testing.T) { + // issue 9456. + switch runtime.GOOS { + case "plan9", "windows": + t.Skipf("no pthreads on %s", runtime.GOOS) + case "darwin": + // static constructor needs external linking, but we don't support + // external linking on OS X 10.6. + out, err := exec.Command("uname", "-r").Output() + if err != nil { + t.Fatalf("uname -r failed: %v", err) + } + // OS X 10.6 == Darwin 10.x + if strings.HasPrefix(string(out), "10.") { + t.Skipf("no external linking on OS X 10.6") + } + } + got := executeTest(t, cgoExternalThreadSIGPROFSource, nil) + want := "OK\n" + if got != want { + t.Fatalf("expected %q, but got %q", want, got) + } +} + const cgoSignalDeadlockSource = ` package main @@ -194,3 +219,46 @@ start(void) printf("_beginthreadex failed\n"); } ` + +const cgoExternalThreadSIGPROFSource = ` +package main + +/* +#include <stdint.h> +#include <signal.h> +#include <pthread.h> + +volatile int32_t spinlock; + +static void *thread1(void *p) { + (void)p; + while (spinlock == 0) + ; + pthread_kill(pthread_self(), SIGPROF); + spinlock = 0; + return NULL; +} +__attribute__((constructor)) void issue9456() { + pthread_t tid; + pthread_create(&tid, 0, thread1, NULL); +} +*/ +import "C" + +import ( + "runtime" + "sync/atomic" + "unsafe" +) + +func main() { + // This test intends to test that sending SIGPROF to foreign threads + // before we make any cgo call will not abort the whole process, so + // we cannot make any cgo call here. See http://golang.org/issue/9456. + atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1) + for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 { + runtime.Gosched() + } + println("OK") +} +` diff --git a/src/runtime/defs_windows.go b/src/runtime/defs_windows.go index 7ce679741..5dfb83a7c 100644 --- a/src/runtime/defs_windows.go +++ b/src/runtime/defs_windows.go @@ -41,6 +41,7 @@ const ( DUPLICATE_SAME_ACCESS = C.DUPLICATE_SAME_ACCESS THREAD_PRIORITY_HIGHEST = C.THREAD_PRIORITY_HIGHEST + SIGPROF = 0 // dummy value for badsignal SIGINT = C.SIGINT CTRL_C_EVENT = C.CTRL_C_EVENT CTRL_BREAK_EVENT = C.CTRL_BREAK_EVENT diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index b4e624423..791af8cf3 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -117,12 +117,12 @@ type hmap struct { // A bucket for a Go map. type bmap struct { - tophash [bucketCnt]uint8 - overflow *bmap + tophash [bucketCnt]uint8 // Followed by bucketCnt keys and then bucketCnt values. // NOTE: packing all the keys together and then all the values together makes the // code a bit more complicated than alternating key/value/key/value/... but it allows // us to eliminate padding which would be needed for, e.g., map[int64]int8. + // Followed by an overflow pointer. } // A hash iteration structure. @@ -149,6 +149,13 @@ func evacuated(b *bmap) bool { return h > empty && h < minTopHash } +func (b *bmap) overflow(t *maptype) *bmap { + return *(**bmap)(add(unsafe.Pointer(b), uintptr(t.bucketsize)-regSize)) +} +func (b *bmap) setoverflow(t *maptype, ovf *bmap) { + *(**bmap)(add(unsafe.Pointer(b), uintptr(t.bucketsize)-regSize)) = ovf +} + func makemap(t *maptype, hint int64) *hmap { if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != uintptr(t.hmap.size) { gothrow("bad hmap size") @@ -275,7 +282,7 @@ func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer { return v } } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero) } @@ -323,7 +330,7 @@ func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) return v, true } } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero), false } @@ -366,7 +373,7 @@ func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe return k, v } } - b = b.overflow + b = b.overflow(t) if b == nil { return nil, nil } @@ -437,10 +444,11 @@ again: memmove(v2, val, uintptr(t.elem.size)) return } - if b.overflow == nil { + ovf := b.overflow(t) + if ovf == nil { break } - b = b.overflow + b = ovf } // did not find mapping for key. Allocate new cell & add entry. @@ -455,7 +463,7 @@ again: memstats.next_gc = memstats.heap_alloc } newb := (*bmap)(newobject(t.bucket)) - b.overflow = newb + b.setoverflow(t, newb) inserti = &newb.tophash[0] insertk = add(unsafe.Pointer(newb), dataOffset) insertv = add(insertk, bucketCnt*uintptr(t.keysize)) @@ -525,7 +533,7 @@ func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) { h.count-- return } - b = b.overflow + b = b.overflow(t) if b == nil { return } @@ -720,7 +728,7 @@ next: return } } - b = b.overflow + b = b.overflow(t) i = 0 goto next } @@ -778,7 +786,7 @@ func evacuate(t *maptype, h *hmap, oldbucket uintptr) { yk := add(unsafe.Pointer(y), dataOffset) xv := add(xk, bucketCnt*uintptr(t.keysize)) yv := add(yk, bucketCnt*uintptr(t.keysize)) - for ; b != nil; b = b.overflow { + for ; b != nil; b = b.overflow(t) { k := add(unsafe.Pointer(b), dataOffset) v := add(k, bucketCnt*uintptr(t.keysize)) for i := 0; i < bucketCnt; i, k, v = i+1, add(k, uintptr(t.keysize)), add(v, uintptr(t.valuesize)) { @@ -828,7 +836,7 @@ func evacuate(t *maptype, h *hmap, oldbucket uintptr) { memstats.next_gc = memstats.heap_alloc } newx := (*bmap)(newobject(t.bucket)) - x.overflow = newx + x.setoverflow(t, newx) x = newx xi = 0 xk = add(unsafe.Pointer(x), dataOffset) @@ -855,7 +863,7 @@ func evacuate(t *maptype, h *hmap, oldbucket uintptr) { memstats.next_gc = memstats.heap_alloc } newy := (*bmap)(newobject(t.bucket)) - y.overflow = newy + y.setoverflow(t, newy) y = newy yi = 0 yk = add(unsafe.Pointer(y), dataOffset) @@ -881,7 +889,6 @@ func evacuate(t *maptype, h *hmap, oldbucket uintptr) { // Unlink the overflow buckets & clear key/value to help GC. if h.flags&oldIterator == 0 { b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))) - b.overflow = nil memclr(add(unsafe.Pointer(b), dataOffset), uintptr(t.bucketsize)-dataOffset) } } diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go index 8e21e02d6..afa6ecc99 100644 --- a/src/runtime/hashmap_fast.go +++ b/src/runtime/hashmap_fast.go @@ -43,7 +43,7 @@ func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer { } return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize)) } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero) } @@ -85,7 +85,7 @@ func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) { } return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize)), true } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero), false } @@ -127,7 +127,7 @@ func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer { } return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize)) } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero) } @@ -169,7 +169,7 @@ func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) { } return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize)), true } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero), false } @@ -271,7 +271,7 @@ dohash: return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)) } } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero) } @@ -371,7 +371,7 @@ dohash: return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true } } - b = b.overflow + b = b.overflow(t) if b == nil { return unsafe.Pointer(t.elem.zero), false } diff --git a/src/runtime/mprof.go b/src/runtime/mprof.go index d409c6c30..f4da45f5c 100644 --- a/src/runtime/mprof.go +++ b/src/runtime/mprof.go @@ -575,20 +575,16 @@ func saveg(pc, sp uintptr, gp *g, r *StackRecord) { // If all is true, Stack formats stack traces of all other goroutines // into buf after the trace for the current goroutine. func Stack(buf []byte, all bool) int { - mp := acquirem() - gp := mp.curg if all { semacquire(&worldsema, false) - mp.gcing = 1 - releasem(mp) + gp := getg() + gp.m.gcing = 1 onM(stoptheworld) - if mp != acquirem() { - gothrow("Stack: rescheduled") - } } n := 0 if len(buf) > 0 { + gp := getg() sp := getcallersp(unsafe.Pointer(&buf)) pc := getcallerpc(unsafe.Pointer(&buf)) onM(func() { @@ -605,11 +601,11 @@ func Stack(buf []byte, all bool) int { } if all { - mp.gcing = 0 + gp := getg() + gp.m.gcing = 0 semrelease(&worldsema) onM(starttheworld) } - releasem(mp) return n } diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go index 20e47bf42..10e5531ec 100644 --- a/src/runtime/os_plan9.go +++ b/src/runtime/os_plan9.go @@ -6,6 +6,8 @@ package runtime import "unsafe" +const _SIGPROF = 0 // dummy value for badsignal + func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 func seek(fd int32, offset int64, whence int32) int64 diff --git a/src/runtime/sigqueue.go b/src/runtime/sigqueue.go index 2d9c24d2d..fed4560fe 100644 --- a/src/runtime/sigqueue.go +++ b/src/runtime/sigqueue.go @@ -154,6 +154,15 @@ func signal_disable(s uint32) { // This runs on a foreign stack, without an m or a g. No stack split. //go:nosplit func badsignal(sig uintptr) { + // Some external libraries, for example, OpenBLAS, create worker threads in + // a global constructor. If we're doing cpu profiling, and the SIGPROF signal + // comes to one of the foreign threads before we make our first cgo call, the + // call to cgocallback below will bring down the whole process. + // It's better to miss a few SIGPROF signals than to abort in this case. + // See http://golang.org/issue/9456. + if _SIGPROF != 0 && sig == _SIGPROF && needextram != 0 { + return + } cgocallback(unsafe.Pointer(funcPC(sigsend)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig)) } diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go index efbcab510..5b76ad573 100644 --- a/src/runtime/syscall_windows.go +++ b/src/runtime/syscall_windows.go @@ -8,6 +8,8 @@ import ( "unsafe" ) +const _SIGPROF = 0 // dummy value for badsignal + type callbacks struct { lock mutex ctxt [cb_max]*wincallbackcontext diff --git a/src/syscall/route_openbsd.go b/src/syscall/route_openbsd.go index 19f902db7..e5086400c 100644 --- a/src/syscall/route_openbsd.go +++ b/src/syscall/route_openbsd.go @@ -12,16 +12,16 @@ func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage { switch any.Type { case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE: p := (*RouteMessage)(unsafe.Pointer(any)) - return &RouteMessage{Header: p.Header, Data: b[SizeofRtMsghdr:any.Msglen]} + return &RouteMessage{Header: p.Header, Data: b[p.Header.Hdrlen:any.Msglen]} case RTM_IFINFO: p := (*InterfaceMessage)(unsafe.Pointer(any)) - return &InterfaceMessage{Header: p.Header, Data: b[SizeofIfMsghdr:any.Msglen]} + return &InterfaceMessage{Header: p.Header, Data: b[p.Header.Hdrlen:any.Msglen]} case RTM_IFANNOUNCE: p := (*InterfaceAnnounceMessage)(unsafe.Pointer(any)) return &InterfaceAnnounceMessage{Header: p.Header} case RTM_NEWADDR, RTM_DELADDR: p := (*InterfaceAddrMessage)(unsafe.Pointer(any)) - return &InterfaceAddrMessage{Header: p.Header, Data: b[SizeofIfaMsghdr:any.Msglen]} + return &InterfaceAddrMessage{Header: p.Header, Data: b[p.Header.Hdrlen:any.Msglen]} } return nil } diff --git a/test/fixedbugs/issue9321.go b/test/fixedbugs/issue9321.go new file mode 100644 index 000000000..06cb5a6e3 --- /dev/null +++ b/test/fixedbugs/issue9321.go @@ -0,0 +1,37 @@ +// run + +// Copyright 2014 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 ( + "bytes" + "runtime" + "runtime/pprof" + "sync" +) + +func test() { + var wg sync.WaitGroup + wg.Add(2) + test := func() { + for i := 0; i < 100; i++ { + buf := &bytes.Buffer{} + pprof.Lookup("goroutine").WriteTo(buf, 2) + } + wg.Done() + } + + go test() + go test() + wg.Wait() +} + +func main() { + runtime.GOMAXPROCS(2) + for i := 0; i < 100; i++ { + test() + } +} |