From 355f25305b058f9975ce61401d7226e376e2db77 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 24 Nov 2014 20:18:44 -0500 Subject: [PATCH 01/12] go/build: build $GOOS_test.go always We decided to build $GOOS.go always but forgot to test $GOOS_test.go. Fixes #9159. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/176290043 --- src/go/build/build.go | 8 +++++--- src/go/build/build_test.go | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/go/build/build.go b/src/go/build/build.go index 7a51cf3c06..311ecb01f4 100644 --- a/src/go/build/build.go +++ b/src/go/build/build.go @@ -1310,11 +1310,13 @@ func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool { // auto-tagging to apply only to files with a non-empty prefix, so // "foo_linux.go" is tagged but "linux.go" is not. This allows new operating // sytems, such as android, to arrive without breaking existing code with - // innocuous source code in "android.go". The easiest fix: files without - // underscores are always included. - if !strings.ContainsRune(name, '_') { + // innocuous source code in "android.go". The easiest fix: cut everything + // in the name before the initial _. + i := strings.Index(name, "_") + if i < 0 { return true } + name = name[i:] // ignore everything before first _ l := strings.Split(name, "_") if n := len(l); n > 0 && l[n-1] == "test" { diff --git a/src/go/build/build_test.go b/src/go/build/build_test.go index 43d09cbd14..a40def0fa0 100644 --- a/src/go/build/build_test.go +++ b/src/go/build/build_test.go @@ -189,6 +189,7 @@ var matchFileTests = []struct { {ctxtAndroid, "foo_plan9.go", "", false}, {ctxtAndroid, "android.go", "", true}, {ctxtAndroid, "plan9.go", "", true}, + {ctxtAndroid, "plan9_test.go", "", true}, {ctxtAndroid, "arm.s", "", true}, {ctxtAndroid, "amd64.s", "", true}, } From c1374b5c7806c97d627017a3bfb5d41470f89b0e Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Tue, 25 Nov 2014 15:41:33 +1100 Subject: [PATCH 02/12] doc: tidy up "Projects" page; add Go 1.4 LGTM=r R=r CC=golang-codereviews https://golang.org/cl/182750043 --- doc/contrib.html | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/doc/contrib.html b/doc/contrib.html index a615fc67a3..8a674d647c 100644 --- a/doc/contrib.html +++ b/doc/contrib.html @@ -30,21 +30,16 @@ We encourage all Go users to subscribe to

Version history

Release History

-

A summary of the changes between Go releases.

-

Go 1 Release Notes

-

-A guide for updating your code to work with Go 1. -

+

A summary of the changes between Go releases. Notes for the major releases:

-

Go 1.1 Release Notes

-

-A list of significant changes in Go 1.1, with instructions for updating -your code where necessary. -Each point release includes a similar document appropriate for that -release: Go 1.2, Go 1.3, -and so on. -

+

Go 1 and the Future of Go Programs

From 7c1e33033ddc2370c468b0f3087d5a584dfd2c7e Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Mon, 1 Dec 2014 07:52:09 -0800 Subject: [PATCH 03/12] reflect: Fix reflect.funcLayout. The GC bitmap has two bits per pointer, not one. Fixes #9179 LGTM=iant, rsc R=golang-codereviews, iant, rsc CC=golang-codereviews https://golang.org/cl/182160043 --- src/reflect/all_test.go | 101 +++++++++++++++++++++++++++++++++++++ src/reflect/export_test.go | 19 +++++++ src/reflect/type.go | 4 +- 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 268a9e319f..7a01c95d86 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -4055,3 +4055,104 @@ func TestLargeGCProg(t *testing.T) { fv := ValueOf(func([256]*byte) {}) fv.Call([]Value{ValueOf([256]*byte{})}) } + +// Issue 9179. +func TestCallGC(t *testing.T) { + f := func(a, b, c, d, e string) { + } + g := func(in []Value) []Value { + runtime.GC() + return nil + } + typ := ValueOf(f).Type() + f2 := MakeFunc(typ, g).Interface().(func(string, string, string, string, string)) + f2("four", "five5", "six666", "seven77", "eight888") +} + +type funcLayoutTest struct { + rcvr, t Type + argsize, retOffset uintptr + stack []byte +} + +var funcLayoutTests []funcLayoutTest + +func init() { + var argAlign = PtrSize + if runtime.GOARCH == "amd64p32" { + argAlign = 2 * PtrSize + } + roundup := func(x uintptr, a uintptr) uintptr { + return (x + a - 1) / a * a + } + + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + nil, + ValueOf(func(a, b string) string { return "" }).Type(), + 4 * PtrSize, + 4 * PtrSize, + []byte{BitsPointer, BitsScalar, BitsPointer}, + }) + + var r []byte + if PtrSize == 4 { + r = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer} + } else { + r = []byte{BitsScalar, BitsScalar, BitsPointer} + } + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + nil, + ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(), + roundup(3*4, PtrSize) + PtrSize + 2, + roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign), + r, + }) + + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + nil, + ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(), + 4 * PtrSize, + 4 * PtrSize, + []byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer}, + }) + + type S struct { + a, b uintptr + c, d *byte + } + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + nil, + ValueOf(func(a S) {}).Type(), + 4 * PtrSize, + 4 * PtrSize, + []byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer}, + }) + + funcLayoutTests = append(funcLayoutTests, + funcLayoutTest{ + ValueOf((*byte)(nil)).Type(), + ValueOf(func(a uintptr, b *int) {}).Type(), + 3 * PtrSize, + roundup(3*PtrSize, argAlign), + []byte{BitsPointer, BitsScalar, BitsPointer}, + }) +} + +func TestFuncLayout(t *testing.T) { + for _, lt := range funcLayoutTests { + _, argsize, retOffset, stack := FuncLayout(lt.t, lt.rcvr) + if argsize != lt.argsize { + t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize) + } + if retOffset != lt.retOffset { + t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.t, lt.rcvr, retOffset, lt.retOffset) + } + if !bytes.Equal(stack, lt.stack) { + t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack) + } + } +} diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go index 0778ad37f5..caaf51a50f 100644 --- a/src/reflect/export_test.go +++ b/src/reflect/export_test.go @@ -17,3 +17,22 @@ func IsRO(v Value) bool { var ArrayOf = arrayOf var CallGC = &callGC + +const PtrSize = ptrSize +const BitsPointer = bitsPointer +const BitsScalar = bitsScalar + +func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack []byte) { + var ft *rtype + var s *bitVector + if rcvr != nil { + ft, argSize, retOffset, s = funcLayout(t.(*rtype), rcvr.(*rtype)) + } else { + ft, argSize, retOffset, s = funcLayout(t.(*rtype), nil) + } + frametype = ft + for i := uint32(0); i < s.n; i += 2 { + stack = append(stack, s.data[i/8]>>(i%8)&3) + } + return +} diff --git a/src/reflect/type.go b/src/reflect/type.go index 572e611fa9..c0ddfcad0a 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -1894,14 +1894,14 @@ func addTypeBits(bv *bitVector, offset *uintptr, t *rtype) { switch Kind(t.kind & kindMask) { case Chan, Func, Map, Ptr, Slice, String, UnsafePointer: // 1 pointer at start of representation - for bv.n < uint32(*offset/uintptr(ptrSize)) { + for bv.n < 2*uint32(*offset/uintptr(ptrSize)) { bv.append2(bitsScalar) } bv.append2(bitsPointer) case Interface: // 2 pointers - for bv.n < uint32(*offset/uintptr(ptrSize)) { + for bv.n < 2*uint32(*offset/uintptr(ptrSize)) { bv.append2(bitsScalar) } bv.append2(bitsPointer) From 2b62e1eaece7c98444a588e2f2a3dbed8dddc273 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 1 Dec 2014 16:32:06 -0500 Subject: [PATCH 04/12] runtime: fix hang in GC due to shrinkstack vs netpoll race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During garbage collection, after scanning a stack, we think about shrinking it to reclaim some memory. The shrinking code (called while the world is stopped) checked that the status was Gwaiting or Grunnable and then changed the state to Gcopystack, to essentially lock the stack so that no other GC thread is scanning it. The same locking happens for stack growth (and is more necessary there). oldstatus = runtime·readgstatus(gp); oldstatus &= ~Gscan; if(oldstatus == Gwaiting || oldstatus == Grunnable) runtime·casgstatus(gp, oldstatus, Gcopystack); // oldstatus is Gwaiting or Grunnable else runtime·throw("copystack: bad status, not Gwaiting or Grunnable"); Unfortunately, "stop the world" doesn't stop everything. It stops all normal goroutine execution, but the network polling thread is still blocked in epoll and may wake up. If it does, and it chooses a goroutine to mark runnable, and that goroutine is the one whose stack is shrinking, then it can happen that between readgstatus and casgstatus, the status changes from Gwaiting to Grunnable. casgstatus assumes that if the status is not what is expected, it is a transient change (like from Gwaiting to Gscanwaiting and back, or like from Gwaiting to Gcopystack and back), and it loops until the status has been restored to the expected value. In this case, the status has changed semi-permanently from Gwaiting to Grunnable - it won't change again until the GC is done and the world can continue, but the GC is waiting for the status to change back. This wedges the program. To fix, call a special variant of casgstatus that accepts either Gwaiting or Grunnable as valid statuses. Without the fix bug with the extra check+throw in casgstatus, the program below dies in a few seconds (2-10) with GOMAXPROCS=8 on a 2012 Retina MacBook Pro. With the fix, it runs for minutes and minutes. package main import ( "io" "log" "net" "runtime" ) func main() { const N = 100 for i := 0; i < N; i++ { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { log.Fatal(err) } ch := make(chan net.Conn, 1) go func() { var err error c1, err := net.Dial("tcp", l.Addr().String()) if err != nil { log.Fatal(err) } ch <- c1 }() c2, err := l.Accept() if err != nil { log.Fatal(err) } c1 := <-ch l.Close() go netguy(c1, c2) go netguy(c2, c1) c1.Write(make([]byte, 100)) } for { runtime.GC() } } func netguy(r, w net.Conn) { buf := make([]byte, 100) for { bigstack(1000) _, err := io.ReadFull(r, buf) if err != nil { log.Fatal(err) } w.Write(buf) } } var g int func bigstack(n int) { var buf [100]byte if n > 0 { bigstack(n - 1) } g = int(buf[0]) + int(buf[99]) } Fixes #9186. LGTM=rlh R=austin, rlh CC=dvyukov, golang-codereviews, iant, khr, r https://golang.org/cl/179680043 --- src/runtime/proc.c | 32 ++++++++++++++++++++++++++++++++ src/runtime/runtime.h | 2 ++ src/runtime/stack.c | 7 +------ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/runtime/proc.c b/src/runtime/proc.c index 91e3fe16d6..8462c4b1d6 100644 --- a/src/runtime/proc.c +++ b/src/runtime/proc.c @@ -402,6 +402,7 @@ runtime·castogscanstatus(G *gp, uint32 oldval, uint32 newval) static void badcasgstatus(void); static void helpcasgstatus(void); +static void badgstatusrunnable(void); // If asked to move to or from a Gscanstatus this will throw. Use the castogscanstatus // and casfromgscanstatus instead. @@ -423,6 +424,10 @@ runtime·casgstatus(G *gp, uint32 oldval, uint32 newval) // loop if gp->atomicstatus is in a scan state giving // GC time to finish and change the state to oldval. while(!runtime·cas(&gp->atomicstatus, oldval, newval)) { + if(oldval == Gwaiting && gp->atomicstatus == Grunnable) { + fn = badgstatusrunnable; + runtime·onM(&fn); + } // Help GC if needed. if(gp->preemptscan && !gp->gcworkdone && (oldval == Grunning || oldval == Gsyscall)) { gp->preemptscan = false; @@ -433,6 +438,33 @@ runtime·casgstatus(G *gp, uint32 oldval, uint32 newval) } } +static void +badgstatusrunnable(void) +{ + runtime·throw("casgstatus: waiting for Gwaiting but is Grunnable"); +} + +// casgstatus(gp, oldstatus, Gcopystack), assuming oldstatus is Gwaiting or Grunnable. +// Returns old status. Cannot call casgstatus directly, because we are racing with an +// async wakeup that might come in from netpoll. If we see Gwaiting from the readgstatus, +// it might have become Grunnable by the time we get to the cas. If we called casgstatus, +// it would loop waiting for the status to go back to Gwaiting, which it never will. +#pragma textflag NOSPLIT +uint32 +runtime·casgcopystack(G *gp) +{ + uint32 oldstatus; + + for(;;) { + oldstatus = runtime·readgstatus(gp) & ~Gscan; + if(oldstatus != Gwaiting && oldstatus != Grunnable) + runtime·throw("copystack: bad status, not Gwaiting or Grunnable"); + if(runtime·cas(&gp->atomicstatus, oldstatus, Gcopystack)) + break; + } + return oldstatus; +} + static void badcasgstatus(void) { diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 977c4547df..177a1287ec 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -666,6 +666,8 @@ enum { uint32 runtime·readgstatus(G*); void runtime·casgstatus(G*, uint32, uint32); +void runtime·casgstatus(G*, uint32, uint32); +uint32 runtime·casgcopystack(G*); void runtime·quiesce(G*); bool runtime·stopg(G*); void runtime·restartg(G*); diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 072bc242bc..cb9557243b 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -637,12 +637,7 @@ copystack(G *gp, uintptr newsize) } runtime·memmove((byte*)new.hi - used, (byte*)old.hi - used, used); - oldstatus = runtime·readgstatus(gp); - oldstatus &= ~Gscan; - if(oldstatus == Gwaiting || oldstatus == Grunnable) - runtime·casgstatus(gp, oldstatus, Gcopystack); // oldstatus is Gwaiting or Grunnable - else - runtime·throw("copystack: bad status, not Gwaiting or Grunnable"); + oldstatus = runtime·casgcopystack(gp); // cas from Gwaiting or Grunnable to Gcopystack, return old status // Swap out old stack for new one gp->stack = new; From ce5d7cffe8c69e2097ae878b8b7cfb6b2265bf69 Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Tue, 2 Dec 2014 14:39:23 +1100 Subject: [PATCH 05/12] tag go1.4rc2 LGTM=rsc R=rsc CC=golang-codereviews https://golang.org/cl/178600043 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 9867bc339f..eb9e82e408 100644 --- a/.hgtags +++ b/.hgtags @@ -137,3 +137,4 @@ f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 go1.3.3 f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 release 1fdfd7dfaedb1b7702141617e621ab7328a236a1 go1.4beta1 bffdd0cae380ce1ccf3e98ed6b6cd53fece7ba72 go1.4rc1 +6c4e66ae713704840fcea78c8055b44ba86ae5ea go1.4rc2 From 14948481f60accb7d7062f2f1d4f4cc50fb4e140 Mon Sep 17 00:00:00 2001 From: Dominik Honnef Date: Wed, 3 Dec 2014 10:28:54 +1100 Subject: [PATCH 06/12] cmd/go: regenerate doc.go Move change from CL 170770043 to correct file and regenerate docs for changes from CL 164120043. LGTM=adg R=golang-codereviews, adg, bradfitz CC=golang-codereviews https://golang.org/cl/183000043 --- src/cmd/go/doc.go | 7 ++++++- src/cmd/go/generate.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go index 43a3159440..879fc7f8ba 100644 --- a/src/cmd/go/doc.go +++ b/src/cmd/go/doc.go @@ -317,7 +317,7 @@ Download and install packages and dependencies Usage: - go get [-d] [-fix] [-t] [-u] [build flags] [packages] + go get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages] Get downloads and installs the packages named by the import paths, along with their dependencies. @@ -325,6 +325,11 @@ along with their dependencies. The -d flag instructs get to stop after downloading the packages; that is, it instructs get not to install the packages. +The -f flag, valid only when -u is set, forces get -u not to verify that +each package has been checked out from the source control repository +implied by its import path. This can be useful if the source is a local fork +of the original. + The -fix flag instructs get to run the fix tool on the downloaded packages before resolving dependencies or building the code. diff --git a/src/cmd/go/generate.go b/src/cmd/go/generate.go index a83cce8f7a..2772452dd5 100644 --- a/src/cmd/go/generate.go +++ b/src/cmd/go/generate.go @@ -45,7 +45,7 @@ The arguments are space-separated tokens or double-quoted strings passed to the generator as individual arguments when it is run. Quoted strings use Go syntax and are evaluated before execution; a -quoted string appears a single argument to the generator. +quoted string appears as a single argument to the generator. Go generate sets several variables when it runs the generator: From 9f04a62a39133439e20ea32a658cc35c21d33729 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 3 Dec 2014 14:14:00 -0500 Subject: [PATCH 07/12] cmd/pprof: fix symbol resolution for remote profiles Fixes #9199. LGTM=iant R=golang-codereviews, iant CC=austin, golang-codereviews, minux https://golang.org/cl/183080043 --- src/cmd/pprof/internal/symbolizer/symbolizer.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cmd/pprof/internal/symbolizer/symbolizer.go b/src/cmd/pprof/internal/symbolizer/symbolizer.go index cabddaa76e..86de5640d2 100644 --- a/src/cmd/pprof/internal/symbolizer/symbolizer.go +++ b/src/cmd/pprof/internal/symbolizer/symbolizer.go @@ -32,6 +32,10 @@ func Symbolize(mode string, prof *profile.Profile, obj plugin.ObjTool, ui plugin } } + if len(prof.Mapping) == 0 { + return fmt.Errorf("no known mappings") + } + mt, err := newMapping(prof, obj, ui, force) if err != nil { return err From 583b29cb18e5dd93d71b79622e23d44833ab1715 Mon Sep 17 00:00:00 2001 From: David Symonds Date: Thu, 4 Dec 2014 09:29:29 +1100 Subject: [PATCH 08/12] spec: add comment marker for consistency. LGTM=r R=gri, r CC=golang-codereviews https://golang.org/cl/185830043 --- doc/go_spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index ca0deb56a3..3b67f307f6 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -5579,7 +5579,7 @@ s3 := append(s2, s0...) // append a slice s3 == []int{0, s4 := append(s3[3:6], s3[2:]...) // append overlapping slice s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0} var t []interface{} -t = append(t, 42, 3.1415, "foo") t == []interface{}{42, 3.1415, "foo"} +t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"} var b []byte b = append(b, "bar"...) // append string contents b == []byte{'b', 'a', 'r' } From b2950a2931bd89323569c1389f780f2cd744e12c Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Wed, 3 Dec 2014 20:07:48 -0800 Subject: [PATCH 09/12] lib/time: update to ICANN time zone database 2014j Fixes #9189. LGTM=dsymonds R=golang-codereviews, dsymonds CC=golang-codereviews https://golang.org/cl/178660043 --- lib/time/update.bash | 4 ++-- lib/time/zoneinfo.zip | Bin 358933 -> 360713 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/time/update.bash b/lib/time/update.bash index 8e1662afde..caa8450fa6 100755 --- a/lib/time/update.bash +++ b/lib/time/update.bash @@ -7,8 +7,8 @@ # downloaded from the ICANN/IANA distribution. # Versions to use. -CODE=2014d -DATA=2014d +CODE=2014j +DATA=2014j set -e rm -rf work diff --git a/lib/time/zoneinfo.zip b/lib/time/zoneinfo.zip index e0d3afe07434ff1349ee23a2506992c9960f4de6..425d7c98fa1f4bfcc9d642ff2e3d3b5a2c1a5970 100644 GIT binary patch delta 78888 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�(?L(y5RHnf?d)k%iM?Objlamd`-)3@z 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 delta 78660 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%0DNo>x}WtF*|-iggyKBZFIAS*V1a&l$< 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 R3(^*(si$yL1pZ!8{sU1pRBZqN From c9d0c812142be1c8f224012f24d111ba46ccdc10 Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Thu, 4 Dec 2014 11:24:23 -0500 Subject: [PATCH 10/12] cmd/pprof/internal/commands: add command to open browser on windows While we're at there, also add a message to prompt the user to install Graphviz if "dot" command is not found. Fixes #9178. LGTM=adg, alex.brainman, cookieo9, rsc R=rsc, adg, bradfitz, alex.brainman, cookieo9, smyrman CC=golang-codereviews https://golang.org/cl/180380043 --- src/cmd/pprof/internal/commands/commands.go | 26 +++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/cmd/pprof/internal/commands/commands.go b/src/cmd/pprof/internal/commands/commands.go index 6d35820184..51397a3c60 100644 --- a/src/cmd/pprof/internal/commands/commands.go +++ b/src/cmd/pprof/internal/commands/commands.go @@ -11,6 +11,7 @@ import ( "io" "os" "os/exec" + "runtime" "strings" "cmd/pprof/internal/plugin" @@ -71,15 +72,27 @@ func PProf(c Completer, interactive **bool, svgpan **string) Commands { "eog": {c, report.Dot, invokeVisualizer(interactive, invokeDot("svg"), "svg", []string{"eog"}), false, "Visualize graph through eog"}, "evince": {c, report.Dot, invokeVisualizer(interactive, invokeDot("pdf"), "pdf", []string{"evince"}), false, "Visualize graph through evince"}, "gv": {c, report.Dot, invokeVisualizer(interactive, invokeDot("ps"), "ps", []string{"gv --noantialias"}), false, "Visualize graph through gv"}, - "web": {c, report.Dot, invokeVisualizer(interactive, saveSVGToFile(svgpan), "svg", browsers), false, "Visualize graph through web browser"}, + "web": {c, report.Dot, invokeVisualizer(interactive, saveSVGToFile(svgpan), "svg", browsers()), false, "Visualize graph through web browser"}, // Visualize HTML directly generated by report. - "weblist": {c, report.WebList, invokeVisualizer(interactive, awayFromTTY("html"), "html", browsers), true, "Output annotated source in HTML for functions matching regexp or address"}, + "weblist": {c, report.WebList, invokeVisualizer(interactive, awayFromTTY("html"), "html", browsers()), true, "Output annotated source in HTML for functions matching regexp or address"}, } } -// List of web browsers to attempt for web visualization -var browsers = []string{"chrome", "google-chrome", "firefox", "/usr/bin/open"} +// browsers returns a list of commands to attempt for web visualization +// on the current platform +func browsers() []string { + cmds := []string{"chrome", "google-chrome", "firefox"} + switch runtime.GOOS { + case "darwin": + cmds = append(cmds, "/usr/bin/open") + case "windows": + cmds = append(cmds, "cmd /c start") + default: + cmds = append(cmds, "xdg-open") + } + return cmds +} // NewCompleter creates an autocompletion function for a set of commands. func NewCompleter(cs Commands) Completer { @@ -142,6 +155,10 @@ func awayFromTTY(format string) PostProcessor { func invokeDot(format string) PostProcessor { divert := awayFromTTY(format) return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error { + if _, err := exec.LookPath("dot"); err != nil { + ui.PrintErr("Cannot find dot, have you installed Graphviz?") + return err + } cmd := exec.Command("dot", "-T"+format) var buf bytes.Buffer cmd.Stdin, cmd.Stdout, cmd.Stderr = input, &buf, os.Stderr @@ -174,6 +191,7 @@ func invokeVisualizer(interactive **bool, format PostProcessor, suffix string, v if err = format(input, tempFile, ui); err != nil { return err } + tempFile.Close() // on windows, if the file is Open, start cannot access it. // Try visualizers until one is successful for _, v := range visualizers { // Separate command and arguments for exec.Command. From dd26fc3822e474112e388f51d59a7257361fb72f Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Fri, 5 Dec 2014 09:15:38 +0900 Subject: [PATCH 11/12] cmd/go: avoid use of bufio.Scanner in generate Scanner can't handle stupid long lines and there are reports of stupid long lines in production. Note the issue isn't long "//go:generate" lines, but any long line in any Go source file. To be fair, if you're going to have a stupid long line it's not a bad bet you'll want to run it through go generate, because it's some embeddable asset that has been machine generated. (One could ask why that generation process didn't add a newline or two, but we should cope anyway.) Rewrite the file scanner in "go generate" so it can handle arbitrarily long lines, and only stores in memory those lines that start "//go:generate". Also: Adjust the documentation to make clear that it does not parse the file. Fixes #9143. Fixes #9196. LGTM=rsc, dominik.honnef R=rsc, cespare, minux, dominik.honnef CC=golang-codereviews https://golang.org/cl/182970043 --- src/cmd/go/doc.go | 21 ++++++++----- src/cmd/go/generate.go | 71 +++++++++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go index 879fc7f8ba..65640fb483 100644 --- a/src/cmd/go/doc.go +++ b/src/cmd/go/doc.go @@ -234,17 +234,24 @@ create or update Go source files, for instance by running yacc. Go generate is never run automatically by go build, go get, go test, and so on. It must be run explicitly. -Directives are written as a whole-line comment of the form +Go generate scans the file for directives, which are lines of +the form, //go:generate command argument... -(note: no space in "//go") where command is the generator to be -run, corresponding to an executable file that can be run locally. -It must either be in the shell path (gofmt), a fully qualified path -(/usr/you/bin/mytool), or a command alias, described below. +(note: no leading spaces and no space in "//go") where command +is the generator to be run, corresponding to an executable file +that can be run locally. It must either be in the shell path +(gofmt), a fully qualified path (/usr/you/bin/mytool), or a +command alias, described below. -The arguments are space-separated tokens or double-quoted strings -passed to the generator as individual arguments when it is run. +Note that go generate does not parse the file, so lines that look +like directives in comments or multiline strings will be treated +as directives. + +The arguments to the directive are space-separated tokens or +double-quoted strings passed to the generator as individual +arguments when it is run. Quoted strings use Go syntax and are evaluated before execution; a quoted string appears as a single argument to the generator. diff --git a/src/cmd/go/generate.go b/src/cmd/go/generate.go index 2772452dd5..88f7efa0f3 100644 --- a/src/cmd/go/generate.go +++ b/src/cmd/go/generate.go @@ -32,17 +32,24 @@ create or update Go source files, for instance by running yacc. Go generate is never run automatically by go build, go get, go test, and so on. It must be run explicitly. -Directives are written as a whole-line comment of the form +Go generate scans the file for directives, which are lines of +the form, //go:generate command argument... -(note: no space in "//go") where command is the generator to be -run, corresponding to an executable file that can be run locally. -It must either be in the shell path (gofmt), a fully qualified path -(/usr/you/bin/mytool), or a command alias, described below. +(note: no leading spaces and no space in "//go") where command +is the generator to be run, corresponding to an executable file +that can be run locally. It must either be in the shell path +(gofmt), a fully qualified path (/usr/you/bin/mytool), or a +command alias, described below. -The arguments are space-separated tokens or double-quoted strings -passed to the generator as individual arguments when it is run. +Note that go generate does not parse the file, so lines that look +like directives in comments or multiline strings will be treated +as directives. + +The arguments to the directive are space-separated tokens or +double-quoted strings passed to the generator as individual +arguments when it is run. Quoted strings use Go syntax and are evaluated before execution; a quoted string appears as a single argument to the generator. @@ -178,13 +185,43 @@ func (g *Generator) run() (ok bool) { fmt.Fprintf(os.Stderr, "%s\n", shortPath(g.path)) } - s := bufio.NewScanner(g.r) - for s.Scan() { - g.lineNum++ - if !bytes.HasPrefix(s.Bytes(), []byte("//go:generate ")) && !bytes.HasPrefix(s.Bytes(), []byte("//go:generate\t")) { + // Scan for lines that start "//go:generate". + // Can't use bufio.Scanner because it can't handle long lines, + // which are likely to appear when using generate. + input := bufio.NewReader(g.r) + var err error + // One line per loop. + for { + g.lineNum++ // 1-indexed. + var buf []byte + buf, err = input.ReadSlice('\n') + if err == bufio.ErrBufferFull { + // Line too long - consume and ignore. + if isGoGenerate(buf) { + g.errorf("directive too long") + } + for err == bufio.ErrBufferFull { + _, err = input.ReadSlice('\n') + } + if err != nil { + break + } continue } - words := g.split(s.Text()) + + if err != nil { + // Check for marker at EOF without final \n. + if err == io.EOF && isGoGenerate(buf) { + err = io.ErrUnexpectedEOF + } + break + } + + if !isGoGenerate(buf) { + continue + } + + words := g.split(string(buf)) if len(words) == 0 { g.errorf("no arguments to directive") } @@ -201,19 +238,23 @@ func (g *Generator) run() (ok bool) { } g.exec(words) } - if s.Err() != nil { - g.errorf("error reading %s: %s", shortPath(g.path), s.Err()) + if err != nil && err != io.EOF { + g.errorf("error reading %s: %s", shortPath(g.path), err) } return true } +func isGoGenerate(buf []byte) bool { + return bytes.HasPrefix(buf, []byte("//go:generate ")) || bytes.HasPrefix(buf, []byte("//go:generate\t")) +} + // split breaks the line into words, evaluating quoted // strings and evaluating environment variables. // The initial //go:generate element is dropped. func (g *Generator) split(line string) []string { // Parse line, obeying quoted strings. var words []string - line = line[len("//go:generate "):] + line = line[len("//go:generate ") : len(line)-1] // Drop preamble and final newline. // One (possibly quoted) word per iteration. Words: for { From 41c6b84342b27353ed40aa3942ef8647631a322b Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Fri, 5 Dec 2014 09:37:56 +0900 Subject: [PATCH 12/12] cmd/go: fix build The new semantics of split require the newline be present. The test was stale. LGTM=adg R=golang-codereviews, adg CC=golang-codereviews https://golang.org/cl/182480043 --- src/cmd/go/generate.go | 2 +- src/cmd/go/generate_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd/go/generate.go b/src/cmd/go/generate.go index 88f7efa0f3..baf4d2b55c 100644 --- a/src/cmd/go/generate.go +++ b/src/cmd/go/generate.go @@ -250,7 +250,7 @@ func isGoGenerate(buf []byte) bool { // split breaks the line into words, evaluating quoted // strings and evaluating environment variables. -// The initial //go:generate element is dropped. +// The initial //go:generate element is present in line. func (g *Generator) split(line string) []string { // Parse line, obeying quoted strings. var words []string diff --git a/src/cmd/go/generate_test.go b/src/cmd/go/generate_test.go index 93c0ae66e9..660ebabbe8 100644 --- a/src/cmd/go/generate_test.go +++ b/src/cmd/go/generate_test.go @@ -40,7 +40,7 @@ func TestGenerateCommandParse(t *testing.T) { } g.setShorthand([]string{"-command", "yacc", "go", "tool", "yacc"}) for _, test := range splitTests { - got := g.split("//go:generate " + test.in) + got := g.split("//go:generate " + test.in + "\n") if !reflect.DeepEqual(got, test.out) { t.Errorf("split(%q): got %q expected %q", test.in, got, test.out) }