]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: attempt to deflake debug_test.go
authorDavid Chase <drchase@google.com>
Wed, 11 Oct 2017 14:28:20 +0000 (10:28 -0400)
committerDavid Chase <drchase@google.com>
Fri, 13 Oct 2017 03:25:23 +0000 (03:25 +0000)
Excluded when -short because it still runs relatively long,
but deflaked.

Removed timeouts from normal path and ensured that they were
not needed and that reference files did not change.

Use "tbreak" instead of "break" with gdb to reduce chance
of multiple hits on main.main.  (Seems not enough, but a
move in the right direction).

By default, testing ignores repeated lines that occur when
nexting.  This appears to sometimes be timing-dependent and
is the observed source of flakiness in testing so far.
Note that these can also be signs of a bug in the generated
debugging output, but it is one of the less-confusing bugs
that can occur.

By default, testing with gdb uses compilation with
inlining disabled to prevent dependence on library code
(it's a bug that library code is seen while Nexting, but
the bug is current behavior).

Also by default exclude all source files outside /testdata
to prevent accidental dependence on library code.  Note that
this is currently only applicable to dlv because (for the
debugging information we produce) gdb does not indicate a
change in the source file for inlined code.

Added flags -i and -r to make gdb testing compile with
inlining and be sensitive to repeats in the next stream.
This is for developer-testing and so we can describe these
problems in bug reports.

Updates #22206.

Change-Id: I9a30ebbc65aa0153fe77b1858cf19743bdc985e4
Reviewed-on: https://go-review.googlesource.com/69930
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/compile/internal/ssa/debug_test.go
src/cmd/compile/internal/ssa/testdata/hist.dbg-dlv.nexts [moved from src/cmd/compile/internal/ssa/testdata/hist-dbg.delve-nexts with 96% similarity]
src/cmd/compile/internal/ssa/testdata/hist.dbg-gdb.nexts [moved from src/cmd/compile/internal/ssa/testdata/hist-dbg.gdb-nexts with 94% similarity]
src/cmd/compile/internal/ssa/testdata/hist.opt-dlv.nexts [moved from src/cmd/compile/internal/ssa/testdata/hist-opt.delve-nexts with 74% similarity]
src/cmd/compile/internal/ssa/testdata/hist.opt-gdb.nexts [moved from src/cmd/compile/internal/ssa/testdata/hist-opt.gdb-nexts with 84% similarity]

index 975c1291a707156ae49a9bb78eadfb56f87a14e7..bc8512cb107b8b10c654e923e2fb1309d79b78b8 100644 (file)
@@ -22,17 +22,21 @@ import (
        "time"
 )
 
-var update = flag.Bool("u", false, "update debug_test reference files")
-var verbose = flag.Bool("v", false, "print more information about what's happening")
-var dryrun = flag.Bool("n", false, "just print the command line and first bits")
-var delve = flag.Bool("d", false, "use delve instead of gdb")
+var update = flag.Bool("u", false, "update test reference files")
+var verbose = flag.Bool("v", false, "print debugger interactions (very verbose)")
+var dryrun = flag.Bool("n", false, "just print the command line and first debugging bits")
+var delve = flag.Bool("d", false, "use Delve (dlv) instead of gdb, use dlv reverence files")
 var force = flag.Bool("f", false, "force run under not linux-amd64; also do not use tempdir")
 
+var repeats = flag.Bool("r", false, "detect repeats in debug steps and don't ignore them")
+var inlines = flag.Bool("i", false, "do inlining for gdb (makes testing flaky till inlining info is correct)")
+
 var hexRe = regexp.MustCompile("0x[a-zA-Z0-9]+")
 var numRe = regexp.MustCompile("-?[0-9]+")
 var stringRe = regexp.MustCompile("\"([^\\\"]|(\\.))*\"")
 
-var gdb = "gdb" // Might be "ggdb" on Darwin, because gdb no longer part of XCode
+var gdb = "gdb"      // Might be "ggdb" on Darwin, because gdb no longer part of XCode
+var debugger = "gdb" // For naming files, etc.
 
 // TestNexting go-builds a file, then uses a debugger (default gdb, optionally delve)
 // to next through the generated executable, recording each line landed at, and
@@ -42,6 +46,25 @@ var gdb = "gdb" // Might be "ggdb" on Darwin, because gdb no longer part of XCod
 // Flag -v is ever-so-slightly verbose.
 // Flag -n is for dry-run, and prints the shell and first debug commands.
 //
+// Because this test (combined with existing compiler deficiencies) is flaky,
+// for gdb-based testing by default inlining is disabled
+// (otherwise output depends on library internals)
+// and for both gdb and dlv by default repeated lines in the next stream are ignored
+// (because this appears to be timing-dependent in gdb, and the cleanest fix is in code common to gdb and dlv).
+//
+// Also by default, any source code outside of .../testdata/ is not mentioned
+// in the debugging histories.  This deals both with inlined library code once
+// the compiler is generating clean inline records, and also deals with
+// runtime code between return from main and process exit.  This is hidden
+// so that those files (in the runtime/library) can change without affecting
+// this test.
+//
+// These choices can be reversed with -i (inlining on) and -r (repeats detected) which
+// will also cause their own failures against the expected outputs.  Note that if the compiler
+// and debugger were behaving properly, the inlined code and repeated lines would not appear,
+// so the expected output is closer to what we hope to see, though it also encodes all our
+// current bugs.
+//
 // The file being tested may contain comments of the form
 // //DBG-TAG=(v1,v2,v3)
 // where DBG = {gdb,dlv} and TAG={dbg,opt}
@@ -60,12 +83,10 @@ var gdb = "gdb" // Might be "ggdb" on Darwin, because gdb no longer part of XCod
 // go test debug_test.go -args -u -d
 
 func TestNexting(t *testing.T) {
-       // Skip this test in an ordinary run.bash.  Too many things
-       // can cause it to break.
+       skipReasons := "" // Many possible skip reasons, list all that apply
        if testing.Short() {
-               t.Skip("skipping in short mode; see issue #22206")
+               skipReasons = "not run in short mode; "
        }
-
        testenv.MustHaveGoBuild(t)
 
        if !*delve && !*force && !(runtime.GOOS == "linux" && runtime.GOARCH == "amd64") {
@@ -75,37 +96,48 @@ func TestNexting(t *testing.T) {
                // Various architectures tend to differ slightly sometimes, and keeping them
                // all in sync is a pain for people who don't have them all at hand,
                // so limit testing to amd64 (for now)
-
-               t.Skip("Skipped unless -d (delve), -f (force), or linux-amd64")
+               skipReasons += "not run unless linux-amd64 or -d or -f; "
        }
 
        if *delve {
+               debugger = "dlv"
                _, err := exec.LookPath("dlv")
                if err != nil {
-                       t.Fatal("dlv specified on command line with -d but no dlv on path")
+                       skipReasons += "not run because dlv (requested by -d option) not on path; "
                }
        } else {
                _, err := exec.LookPath(gdb)
                if err != nil {
                        if runtime.GOOS != "darwin" {
-                               t.Skip("Skipped because gdb not available")
-                       }
-                       _, err = exec.LookPath("ggdb")
-                       if err != nil {
-                               t.Skip("Skipped because gdb (and also ggdb) not available")
+                               skipReasons += "not run because gdb not on path; "
+                       } else {
+                               _, err = exec.LookPath("ggdb")
+                               if err != nil {
+                                       skipReasons += "not run because gdb (and also ggdb) not on path; "
+                               } else {
+                                       gdb = "ggdb"
+                               }
                        }
-                       gdb = "ggdb"
                }
        }
 
-       t.Run("dbg", func(t *testing.T) {
+       if skipReasons != "" {
+               t.Skip(skipReasons[:len(skipReasons)-2])
+       }
+
+       t.Run("dbg-"+debugger, func(t *testing.T) {
                testNexting(t, "hist", "dbg", "-N -l")
        })
-       t.Run("opt", func(t *testing.T) {
+       t.Run("opt-"+debugger, func(t *testing.T) {
                // If this is test is run with a runtime compiled with -N -l, it is very likely to fail.
                // This occurs in the noopt builders (for example).
                if gogcflags := os.Getenv("GO_GCFLAGS"); *force || (!strings.Contains(gogcflags, "-N") && !strings.Contains(gogcflags, "-l")) {
-                       testNexting(t, "hist", "opt", "")
+                       if *delve || *inlines {
+                               testNexting(t, "hist", "opt", "")
+                       } else {
+                               // For gdb, disable inlining so that a compiler test does not depend on library code.
+                               testNexting(t, "hist", "opt", "-l")
+                       }
                } else {
                        t.Skip("skipping for unoptimized runtime")
                }
@@ -115,12 +147,12 @@ func TestNexting(t *testing.T) {
 func testNexting(t *testing.T, base, tag, gcflags string) {
        // (1) In testdata, build sample.go into sample
        // (2) Run debugger gathering a history
-       // (3) Read expected history from testdata/sample.nexts
-       // optionally, write out testdata/sample.nexts
+       // (3) Read expected history from testdata/sample.<variant>.nexts
+       // optionally, write out testdata/sample.<variant>.nexts
 
        exe := filepath.Join("testdata", base)
-       logbase := exe + "-" + tag
-       tmpbase := logbase + "-test"
+       logbase := exe + "." + tag
+       tmpbase := filepath.Join("testdata", "test-"+base+"."+tag)
 
        if !*force {
                tmpdir, err := ioutil.TempDir("", "debug_test")
@@ -141,15 +173,13 @@ func testNexting(t *testing.T, base, tag, gcflags string) {
                runGo(t, "", "build", "-o", exe, "-gcflags", gcflags, filepath.Join("testdata", base+".go"))
        }
        var h1 *nextHist
-       var nextlog, tmplog string
+
+       nextlog := logbase + "-" + debugger + ".nexts"
+       tmplog := tmpbase + "-" + debugger + ".nexts"
        if *delve {
                h1 = dlvTest(tag, exe, 1000)
-               nextlog = logbase + ".delve-nexts"
-               tmplog = tmpbase + ".delve-nexts"
        } else {
                h1 = gdbTest(tag, exe, 1000)
-               nextlog = logbase + ".gdb-nexts"
-               tmplog = tmpbase + ".gdb-nexts"
        }
        if *dryrun {
                fmt.Printf("# Tag for above is %s\n", tag)
@@ -176,12 +206,12 @@ func testNexting(t *testing.T, base, tag, gcflags string) {
 
 type dbgr interface {
        start()
-       do(s string)
        stepnext(s string) bool // step or next, possible with parameter, gets line etc.  returns true for success, false for unsure response
        quit()
        hist() *nextHist
 }
 
+// gdbTest runs the debugger test with gdb and returns the history
 func gdbTest(tag, executable string, maxNext int, args ...string) *nextHist {
        dbg := newGdb(tag, executable, args...)
        dbg.start()
@@ -197,6 +227,7 @@ func gdbTest(tag, executable string, maxNext int, args ...string) *nextHist {
        return h
 }
 
+// dlvTest runs the debugger test with dlv and returns the history
 func dlvTest(tag, executable string, maxNext int, args ...string) *nextHist {
        dbg := newDelve(tag, executable, args...)
        dbg.start()
@@ -234,6 +265,7 @@ func runGo(t *testing.T, dir string, args ...string) string {
        return stdout.String()
 }
 
+// tstring provides two strings, o (stdout) and e (stderr)
 type tstring struct {
        o string
        e string
@@ -245,13 +277,13 @@ func (t tstring) String() string {
 
 type pos struct {
        line uint16
-       file uint8
+       file uint8 // Artifact of plans to implement differencing instead of calling out to diff.
 }
 
 type nextHist struct {
        f2i   map[string]uint8
        fs    []string
-       ps    []pos // TODO: plan to automatically do the minimum distance conversion between a reference and a run for nicer errors.
+       ps    []pos
        texts []string
        vars  [][]string
 }
@@ -310,7 +342,11 @@ func (h *nextHist) read(filename string) {
        }
 }
 
-func (h *nextHist) add(file, line, text string) {
+func (h *nextHist) add(file, line, text string) bool {
+       // Only record source code in testdata unless the inlines flag is set
+       if !*inlines && !strings.Contains(file, "/testdata/") {
+               return false
+       }
        fi := h.f2i[file]
        if fi == 0 {
                h.fs = append(h.fs, file)
@@ -327,9 +363,16 @@ func (h *nextHist) add(file, line, text string) {
                        panic(fmt.Sprintf("Non-numeric line: %s, error %v\n", line, err))
                }
        }
-       h.ps = append(h.ps, pos{line: uint16(li), file: fi})
-       h.texts = append(h.texts, text)
-       h.vars = append(h.vars, []string{})
+       l := len(h.ps)
+       p := pos{line: uint16(li), file: fi}
+
+       if l == 0 || *repeats || h.ps[l-1] != p {
+               h.ps = append(h.ps, p)
+               h.texts = append(h.texts, text)
+               h.vars = append(h.vars, []string{})
+               return true
+       }
+       return false
 }
 
 func (h *nextHist) addVar(text string) {
@@ -369,6 +412,9 @@ func (h *nextHist) equals(k *nextHist) bool {
        return true
 }
 
+// canonFileName strips everything before "src/" from a filename.
+// This makes file names portable across different machines,
+// home directories, and temporary directories.
 func canonFileName(f string) string {
        i := strings.Index(f, "/src/")
        if i != -1 {
@@ -426,9 +472,13 @@ func (s *delveState) stepnext(ss string) bool {
                s.file = fn
                s.function = locations[1]
                s.ioState.history.add(s.file, s.line, excerpt)
+               // TODO: here is where variable processing will be added.  See gdbState.stepnext as a guide.
+               // Adding this may require some amount of normalization so that logs are comparable.
                return true
        }
-       fmt.Printf("DID NOT MATCH EXPECTED NEXT OUTPUT\nO='%s'\nE='%s'\n", x.o, x.e)
+       if *verbose {
+               fmt.Printf("DID NOT MATCH EXPECTED NEXT OUTPUT\nO='%s'\nE='%s'\n", x.o, x.e)
+       }
        return false
 }
 
@@ -445,16 +495,12 @@ func (s *delveState) start() {
                panic(fmt.Sprintf("There was an error [start] running '%s', %v\n", line, err))
        }
        s.ioState.readExpecting(-1, 5000, "Type 'help' for list of commands.")
-       expect("Breakpoint [0-9]+ set at ", s.ioState.writeRead("b main.main\n"))
+       expect("Breakpoint [0-9]+ set at ", s.ioState.writeReadExpect("b main.main\n", "[(]dlv[)] "))
        s.stepnext("c")
 }
 
 func (s *delveState) quit() {
-       s.do("q")
-}
-
-func (s *delveState) do(ss string) {
-       expect("", s.ioState.writeRead(ss+"\n"))
+       expect("", s.ioState.writeRead("q\n"))
 }
 
 /* Gdb */
@@ -493,7 +539,7 @@ func (s *gdbState) start() {
        }
        if *dryrun {
                fmt.Printf("%s\n", asCommandLine("", s.cmd))
-               fmt.Printf("b main.main\n")
+               fmt.Printf("tbreak main.main\n")
                fmt.Printf("%s\n", run)
                return
        }
@@ -502,7 +548,7 @@ func (s *gdbState) start() {
                line := asCommandLine("", s.cmd)
                panic(fmt.Sprintf("There was an error [start] running '%s', %v\n", line, err))
        }
-       s.ioState.readExpecting(-1, 5000, "[(]gdb[)] ")
+       s.ioState.readExpecting(-1, -1, "[(]gdb[)] ")
        x := s.ioState.writeReadExpect("b main.main\n", "[(]gdb[)] ")
        expect("Breakpoint [0-9]+ at", x)
        s.stepnext(run)
@@ -513,8 +559,11 @@ func (s *gdbState) stepnext(ss string) bool {
        excerpts := s.atLineRe.FindStringSubmatch(x.o)
        locations := s.funcFileLinePCre.FindStringSubmatch(x.o)
        excerpt := ""
+       addedLine := false
        if len(excerpts) == 0 && len(locations) == 0 {
-               fmt.Printf("DID NOT MATCH %s", x.o)
+               if *verbose {
+                       fmt.Printf("DID NOT MATCH %s", x.o)
+               }
                return false
        }
        if len(excerpts) > 0 {
@@ -531,16 +580,20 @@ func (s *gdbState) stepnext(ss string) bool {
                s.line = locations[3]
                s.file = fn
                s.function = locations[1]
-               s.ioState.history.add(s.file, s.line, excerpt)
+               addedLine = s.ioState.history.add(s.file, s.line, excerpt)
        }
        if len(excerpts) > 0 {
                if *verbose {
                        fmt.Printf("  %s\n", excerpts[2])
                }
                s.line = excerpts[2]
-               s.ioState.history.add(s.file, s.line, excerpt)
+               addedLine = s.ioState.history.add(s.file, s.line, excerpt)
        }
 
+       if !addedLine {
+               // True if this was a repeat line
+               return true
+       }
        // Look for //gdb-<tag>=(v1,v2,v3) and print v1, v2, v3
        vars := varsToPrint(excerpt, "//gdb-"+s.tag+"=(")
        for _, v := range vars {
@@ -550,7 +603,7 @@ func (s *gdbState) stepnext(ss string) bool {
                        substitutions = v[slashIndex:]
                        v = v[:slashIndex]
                }
-               response := s.ioState.writeRead("p " + v + "\n").String()
+               response := s.ioState.writeReadExpect("p "+v+"\n", "[(]gdb[)] ").String()
                // expect something like "$1 = ..."
                dollar := strings.Index(response, "$")
                cr := strings.Index(response, "\n")
@@ -583,6 +636,10 @@ func (s *gdbState) stepnext(ss string) bool {
        return true
 }
 
+// varsToPrint takes a source code line, and extracts the comma-separated variable names
+// found between lookfor and the next ")".
+// For example, if line includes "... //gdb-foo=(v1,v2,v3)" and
+// lookfor="//gdb-foo=(", then varsToPrint returns ["v1", "v2", "v3"]
 func varsToPrint(line, lookfor string) []string {
        var vars []string
        if strings.Contains(line, lookfor) {
@@ -606,10 +663,6 @@ func (s *gdbState) quit() {
        }
 }
 
-func (s *gdbState) do(ss string) {
-       expect("", s.ioState.writeRead(ss+"\n"))
-}
-
 type ioState struct {
        stdout  io.ReadCloser
        stderr  io.ReadCloser
@@ -685,10 +738,8 @@ func (s *ioState) hist() *nextHist {
        return s.history
 }
 
-const (
-       interlineDelay = 300
-)
-
+// writeRead writes ss, then reads stdout and stderr, waiting 500ms to
+// be sure all the output has appeared.
 func (s *ioState) writeRead(ss string) tstring {
        if *verbose {
                fmt.Printf("=> %s", ss)
@@ -697,31 +748,32 @@ func (s *ioState) writeRead(ss string) tstring {
        if err != nil {
                panic(fmt.Sprintf("There was an error writing '%s', %v\n", ss, err))
        }
-       return s.readWithDelay(-1, interlineDelay)
+       return s.readExpecting(-1, 500, "")
 }
 
-func (s *ioState) writeReadExpect(ss, expect string) tstring {
+// writeReadExpect writes ss, then reads stdout and stderr until something
+// that matches expectRE appears.  expectRE should not be ""
+func (s *ioState) writeReadExpect(ss, expectRE string) tstring {
        if *verbose {
                fmt.Printf("=> %s", ss)
        }
+       if expectRE == "" {
+               panic("expectRE should not be empty; use .* instead")
+       }
        _, err := io.WriteString(s.stdin, ss)
        if err != nil {
                panic(fmt.Sprintf("There was an error writing '%s', %v\n", ss, err))
        }
-       return s.readExpecting(-1, interlineDelay, expect)
-}
-
-func (s *ioState) readWithDelay(millis, interlineTimeout int) tstring {
-       return s.readExpecting(millis, interlineTimeout, "")
+       return s.readExpecting(-1, -1, expectRE)
 }
 
-func (s *ioState) readExpecting(millis, interlineTimeout int, expected string) tstring {
+func (s *ioState) readExpecting(millis, interlineTimeout int, expectedRE string) tstring {
        timeout := time.Millisecond * time.Duration(millis)
        interline := time.Millisecond * time.Duration(interlineTimeout)
        s.last = tstring{}
        var re *regexp.Regexp
-       if expected != "" {
-               re = regexp.MustCompile(expected)
+       if expectedRE != "" {
+               re = regexp.MustCompile(expectedRE)
        }
 loop:
        for {
similarity index 96%
rename from src/cmd/compile/internal/ssa/testdata/hist-dbg.delve-nexts
rename to src/cmd/compile/internal/ssa/testdata/hist.dbg-dlv.nexts
index 4e71550975330b0086c3c8636756dbf7c5b4709c..07de28977c7ce7fc554eb016569c106074f61131 100644 (file)
 61:                            continue
 59:            for i, a := range hist {
 68:    }
-  src/runtime/proc.go
-201:           if atomic.Load(&runningPanicDefers) != 0 {
-210:           if atomic.Load(&panicking) != 0 {
-214:           exit(0)
similarity index 94%
rename from src/cmd/compile/internal/ssa/testdata/hist-dbg.gdb-nexts
rename to src/cmd/compile/internal/ssa/testdata/hist.dbg-gdb.nexts
index 5bb61027291921bdf9a4ac3eab2c4b1cf78dc15a..0ba18c11f19dd5266474e5fd70edf2097d7dd766 100644 (file)
@@ -1,6 +1,5 @@
   src/cmd/compile/internal/ssa/testdata/hist.go
 35:    func main() {
-35:    func main() {
 36:            hist := make([]int, 10)
 37:            var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
 $1 =  []int = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -132,8 +131,3 @@ $24 = 26
 61:                            continue
 59:            for i, a := range hist {
 68:    }
-  src/runtime/proc.go
-201:           if atomic.Load(&runningPanicDefers) != 0 {
-201:           if atomic.Load(&runningPanicDefers) != 0 {
-210:           if atomic.Load(&panicking) != 0 {
-214:           exit(0)
similarity index 74%
rename from src/cmd/compile/internal/ssa/testdata/hist-opt.delve-nexts
rename to src/cmd/compile/internal/ssa/testdata/hist.opt-dlv.nexts
index 659971991ec762ac087871f80968a9c477f9175d..635cb74e9340506ceed31f08af68c4b91f6df987 100644 (file)
 36:            hist := make([]int, 10)
 37:            var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
 13:            "strings"
-  src/strings/reader.go
-150:   func NewReader(s string) *Reader { return &Reader{s, 0, -1} }
-  ./testdata/hist.go
 38:            if len(os.Args) > 1 {
 8:             "bufio"
-  src/bufio/scan.go
-84:                    split:        ScanLines,
-74:            MaxScanTokenSize = 64 * 1024
-  ./testdata/hist.go
 47:            for scanner.Scan() {
-47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-  src/bufio/scan.go
-107:           return string(s.token)
-  ./testdata/hist.go
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
-55:                    hist[int(i)]++
 47:            for scanner.Scan() {
 59:            for i, a := range hist {
 60:                    if a == 0 {
-60:                    if a == 0 {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 64:                    n += a
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 59:            for i, a := range hist {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 60:                    if a == 0 {
-60:                    if a == 0 {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 64:                    n += a
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 59:            for i, a := range hist {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 60:                    if a == 0 {
-60:                    if a == 0 {
-60:                    if a == 0 {
-60:                    if a == 0 {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 64:                    n += a
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 60:                    if a == 0 {
 68:    }
-  src/runtime/proc.go
-201:           if atomic.Load(&runningPanicDefers) != 0 {
-210:           if atomic.Load(&panicking) != 0 {
-214:           exit(0)
similarity index 84%
rename from src/cmd/compile/internal/ssa/testdata/hist-opt.gdb-nexts
rename to src/cmd/compile/internal/ssa/testdata/hist.opt-gdb.nexts
index 66c8bcd46d23c0896b2593354cc1de796f6d0985..037ede00fe72385c7cce1794f9de29a06b7b81c6 100644 (file)
@@ -1,70 +1,65 @@
   src/cmd/compile/internal/ssa/testdata/hist.go
 35:    func main() {
-35:    func main() {
 36:            hist := make([]int, 10)
 37:            var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
-13:            "strings"
-150:   func NewReader(s string) *Reader { return &Reader{s, 0, -1} }
 38:            if len(os.Args) > 1 {
-8:             "bufio"
-84:                    split:        ScanLines,
-74:            MaxScanTokenSize = 64 * 1024
+46:            scanner := bufio.NewScanner(reader)
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
 55:                    hist[int(i)]++
 47:            for scanner.Scan() {
-107:           return string(s.token)
+48:                    s := scanner.Text()
 49:                    i, err := strconv.ParseInt(s, 10, 64)
 50:                    if err != nil { //gdb-dbg=(i)
 54:                    hist = ensure(int(i), hist)
@@ -72,7 +67,6 @@
 47:            for scanner.Scan() {
 59:            for i, a := range hist {
 60:                    if a == 0 {
-60:                    if a == 0 {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 64:                    n += a
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
@@ -93,7 +87,6 @@
 59:            for i, a := range hist {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 60:                    if a == 0 {
-60:                    if a == 0 {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 64:                    n += a
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 59:            for i, a := range hist {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 60:                    if a == 0 {
-60:                    if a == 0 {
-60:                    if a == 0 {
-60:                    if a == 0 {
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 64:                    n += a
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 65:                    fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t)
 60:                    if a == 0 {
 68:    }
-  src/runtime/proc.go
-201:           if atomic.Load(&runningPanicDefers) != 0 {
-201:           if atomic.Load(&runningPanicDefers) != 0 {
-210:           if atomic.Load(&panicking) != 0 {
-214:           exit(0)