s.popLine()
}
+ for _, b := range s.f.Blocks {
+ if b.Pos != src.NoXPos {
+ updateUnsetPredPos(b)
+ }
+ }
+
s.insertPhis()
// Don't carry reference this around longer than necessary
return s.f
}
+func updateUnsetPredPos(b *ssa.Block) {
+ for _, e := range b.Preds {
+ p := e.Block()
+ if p.Pos == src.NoXPos && p.Kind == ssa.BlockPlain {
+ pos := b.Pos
+ // TODO: This ought to be produce a better result, but it causes
+ // line 46 ("scanner := bufio.NewScanner(reader)")
+ // to drop out of gdb-dbg and dlv-dbg debug-next traces for hist.go.
+ for _, v := range b.Values {
+ if v.Op == ssa.OpVarDef || v.Op == ssa.OpVarKill || v.Op == ssa.OpVarLive || v.Op == ssa.OpCopy && v.Type == types.TypeMem {
+ continue
+ }
+ if v.Pos != src.NoXPos {
+ pos = v.Pos
+ break
+ }
+ }
+ p.Pos = pos
+ updateUnsetPredPos(p) // We do not expect long chains of these, thus recursion is okay.
+ }
+ }
+ return
+}
+
type state struct {
// configuration (arch) information
config *ssa.Config
// line number stack. The current line number is top of stack
line []src.XPos
+ // the last line number processed; it may have been popped
+ lastPos src.XPos
// list of panic calls by function name and line number.
// Used to deduplicate panic calls.
s.defvars[b.ID] = s.vars
s.curBlock = nil
s.vars = nil
- b.Pos = s.peekPos()
+ if len(b.Values) == 0 && b.Kind == ssa.BlockPlain {
+ // Empty plain blocks get the line of their successor (handled after all blocks created),
+ // except for increment blocks in For statements (handled in ssa conversion of OFOR),
+ // and for blocks ending in GOTO/BREAK/CONTINUE.
+ b.Pos = src.NoXPos
+ } else {
+ b.Pos = s.lastPos
+ }
return b
}
if Debug['K'] != 0 {
Warn("buildssa: unknown position (line 0)")
}
+ } else {
+ s.lastPos = line
}
+
s.line = append(s.line, line)
}
// stmt converts the statement n to SSA and adds it to s.
func (s *state) stmt(n *Node) {
- s.pushLine(n.Pos)
- defer s.popLine()
+ if !(n.Op == OVARKILL || n.Op == OVARLIVE) {
+ // OVARKILL and OVARLIVE are invisible to the programmer, so we don't use their line numbers to avoid confusion in debugging.
+ s.pushLine(n.Pos)
+ defer s.popLine()
+ }
// If s.curBlock is nil, and n isn't a label (which might have an associated goto somewhere),
// then this code is dead. Stop here.
}
b := s.endBlock()
+ b.Pos = s.lastPos // Do this even if b is an empty block.
b.AddEdgeTo(lab.target)
case OAS:
}
b := s.endBlock()
+ b.Pos = s.lastPos // Do this even if b is an empty block.
b.AddEdgeTo(to)
case OFOR, OFORUNTIL:
}
if b := s.endBlock(); b != nil {
b.AddEdgeTo(bCond)
+ // It can happen that bIncr ends in a block containing only VARKILL,
+ // and that muddles the debugging experience.
+ if n.Op != OFORUNTIL && b.Pos == src.NoXPos {
+ b.Pos = bCond.Pos
+ }
}
if n.Op == OFORUNTIL {
func (s *SSAGenState) oneFPJump(b *ssa.Block, jumps *FloatingEQNEJump) {
p := s.Prog(jumps.Jump)
p.To.Type = obj.TYPE_BRANCH
+ p.Pos = b.Pos
to := jumps.Index
s.Branches = append(s.Branches, Branch{p, b.Succs[to].Block()})
}
s.oneFPJump(b, &jumps[1][0])
s.oneFPJump(b, &jumps[1][1])
q := s.Prog(obj.AJMP)
+ q.Pos = b.Pos
q.To.Type = obj.TYPE_BRANCH
s.Branches = append(s.Branches, Branch{q, b.Succs[1].Block()})
}
--- /dev/null
+// Copyright 2017 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 ssa_test
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "internal/testenv"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+ "testing"
+ "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 force = flag.Bool("f", false, "force run under not linux-amd64; also do not use tempdir")
+
+var hexRe = regexp.MustCompile("0x[a-zA-Z0-9]+")
+var numRe = regexp.MustCompile("-?[0-9]+")
+var stringRe = regexp.MustCompile("\"([^\\\"]|(\\.))*\"")
+
+// 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
+// then compares those lines with reference file(s).
+// Flag -u updates the reference file(s).
+// Flag -d changes the debugger to delve (and uses delve-specific reference files)
+// Flag -v is ever-so-slightly verbose.
+// Flag -n is for dry-run, and prints the shell and first debug commands.
+//
+// The file being tested may contain comments of the form
+// //DBG-TAG=(v1,v2,v3)
+// where DBG = {gdb,dlv} and TAG={dbg,opt}
+// each variable may optionally be followed by a / and one or more of S,A,N
+// to indicate normalization of Strings, (hex) addresses, and numbers.
+// For example:
+/*
+ if len(os.Args) > 1 { //gdb-dbg=(hist/A,cannedInput/A) //dlv-dbg=(hist/A,cannedInput/A)
+*/
+// TODO: not implemented for Delve yet, but this is the plan
+//
+// After a compiler change that causes a difference in the debug behavior, check
+// to see if it is sensible or not, and if it is, update the reference files with
+// go test debug_test.go -args -u
+// (for Delve)
+// go test debug_test.go -args -u -d
+func TestNexting(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ testNexting(t, "hist", "dbg", "-N -l")
+ testNexting(t, "hist", "opt", "")
+}
+
+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
+
+ if !*delve && !*force && !(runtime.GOOS == "linux" && runtime.GOARCH == "amd64") {
+ // Running gdb on OSX/darwin is very flaky.
+ // It also probably requires an admin password typed into a dialog box.
+ // 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()
+ }
+
+ exe := filepath.Join("testdata", base)
+ logbase := exe + "-" + tag
+ tmpbase := logbase + "-test"
+
+ if !*force {
+ tmpdir, err := ioutil.TempDir("", "debug_test")
+ if err != nil {
+ panic(fmt.Sprintf("Problem creating TempDir, error %v\n", err))
+ }
+ exe = filepath.Join(tmpdir, base)
+ tmpbase = exe + "-" + tag + "-test"
+ if *verbose {
+ fmt.Printf("Tempdir is %s\n", tmpdir)
+ }
+ defer os.RemoveAll(tmpdir)
+ }
+
+ if gcflags == "" {
+ runGo(t, "", "build", "-o", exe, filepath.Join("testdata", base+".go"))
+ } else {
+ runGo(t, "", "build", "-o", exe, "-gcflags", gcflags, filepath.Join("testdata", base+".go"))
+ }
+ var h1 *nextHist
+ var nextlog, tmplog string
+ 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)
+ return
+ }
+ if *update {
+ h1.write(nextlog)
+ } else {
+ h0 := &nextHist{}
+ h0.read(nextlog)
+ if !h0.equals(h1) {
+ // Be very noisy about exactly what's wrong to simplify debugging.
+ h1.write(tmplog)
+ cmd := exec.Command("diff", "-u", nextlog, tmplog)
+ line := asCommandLine("", cmd)
+ bytes, err := cmd.CombinedOutput()
+ if err != nil && len(bytes) == 0 {
+ t.Fatalf("step/next histories differ, diff command %s failed with error=%v", line, err)
+ }
+ t.Fatalf("step/next histories differ, diff=\n%s", string(bytes))
+ }
+ }
+}
+
+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
+}
+
+func gdbTest(tag, executable string, maxNext int, args ...string) *nextHist {
+ dbg := newGdb(tag, executable, args...)
+ dbg.start()
+ if *dryrun {
+ return nil
+ }
+ for i := 0; i < maxNext; i++ {
+ if !dbg.stepnext("n") {
+ break
+ }
+ }
+ h := dbg.hist()
+ return h
+}
+
+func dlvTest(tag, executable string, maxNext int, args ...string) *nextHist {
+ dbg := newDelve(tag, executable, args...)
+ dbg.start()
+ if *dryrun {
+ return nil
+ }
+ for i := 0; i < maxNext; i++ {
+ if !dbg.stepnext("n") {
+ break
+ }
+ }
+ h := dbg.hist()
+ return h
+}
+
+func runGo(t *testing.T, dir string, args ...string) string {
+ var stdout, stderr bytes.Buffer
+ cmd := exec.Command(testenv.GoToolPath(t), args...)
+ cmd.Dir = dir
+ if *dryrun {
+ fmt.Printf("%s\n", asCommandLine("", cmd))
+ return ""
+ }
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+
+ if err := cmd.Run(); err != nil {
+ t.Fatalf("error running cmd (%s): %v\nstdout:\n%sstderr:\n%s\n", asCommandLine("", cmd), err, stdout.String(), stderr.String())
+ }
+
+ if s := stderr.String(); s != "" {
+ t.Fatalf("Stderr = %s\nWant empty", s)
+ }
+
+ return stdout.String()
+}
+
+type tstring struct {
+ o string
+ e string
+}
+
+func (t tstring) String() string {
+ return t.o + t.e
+}
+
+type pos struct {
+ line uint16
+ file uint8
+}
+
+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.
+ texts []string
+ vars [][]string
+}
+
+func (h *nextHist) write(filename string) {
+ file, err := os.Create(filename)
+ if err != nil {
+ panic(fmt.Sprintf("Problem opening %s, error %v\n", filename, err))
+ }
+ defer file.Close()
+ var lastfile uint8
+ for i, x := range h.texts {
+ p := h.ps[i]
+ if lastfile != p.file {
+ fmt.Fprintf(file, " %s\n", h.fs[p.file-1])
+ lastfile = p.file
+ }
+ fmt.Fprintf(file, "%d:%s\n", p.line, x)
+ // Vars must begin with a dollar-sign.
+ // TODO, normalize between gdb and dlv into a common, comparable format.
+ for _, y := range h.vars[i] {
+ y = strings.TrimSpace(y)
+ if y[0] != '$' {
+ panic(fmt.Sprintf("Var line '%s' must begin with $, but does not\n", y))
+ }
+ fmt.Fprintf(file, "%s\n", y)
+ }
+ }
+ file.Close()
+}
+
+func (h *nextHist) read(filename string) {
+ h.f2i = make(map[string]uint8)
+ bytes, err := ioutil.ReadFile(filename)
+ if err != nil {
+ panic(fmt.Sprintf("Problem reading %s, error %v\n", filename, err))
+ }
+ var lastfile string
+ lines := strings.Split(string(bytes), "\n")
+ for i, l := range lines {
+ if len(l) > 0 && l[0] != '#' {
+ if l[0] == ' ' {
+ // file -- first two characters expected to be " "
+ lastfile = strings.TrimSpace(l)
+ } else if l[0] == '$' {
+ h.addVar(l)
+ } else {
+ // line number -- <number>:<line>
+ colonPos := strings.Index(l, ":")
+ if colonPos == -1 {
+ panic(fmt.Sprintf("Line %d (%s) in file %s expected to contain '<number>:' but does not.\n", i+1, l, filename))
+ }
+ h.add(lastfile, l[0:colonPos], l[colonPos+1:])
+ }
+ }
+ }
+}
+
+func (h *nextHist) add(file, line, text string) {
+ fi := h.f2i[file]
+ if fi == 0 {
+ h.fs = append(h.fs, file)
+ fi = uint8(len(h.fs))
+ h.f2i[file] = fi
+ }
+
+ line = strings.TrimSpace(line)
+ var li int
+ var err error
+ if line != "" {
+ li, err = strconv.Atoi(line)
+ if err != nil {
+ 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{})
+}
+
+func (h *nextHist) addVar(text string) {
+ l := len(h.texts)
+ h.vars[l-1] = append(h.vars[l-1], text)
+}
+
+func invertMapSU8(hf2i map[string]uint8) map[uint8]string {
+ hi2f := make(map[uint8]string)
+ for hs, i := range hf2i {
+ hsi := strings.Index(hs, "/src/")
+ if hsi != -1 {
+ hs = hs[hsi+1:]
+ }
+ hi2f[i] = hs
+ }
+ return hi2f
+}
+
+func (h *nextHist) equals(k *nextHist) bool {
+ if len(h.f2i) != len(k.f2i) {
+ return false
+ }
+ if len(h.ps) != len(k.ps) {
+ return false
+ }
+ hi2f := invertMapSU8(h.f2i)
+ ki2f := invertMapSU8(k.f2i)
+
+ for i, hs := range hi2f {
+ if hs != ki2f[i] {
+ return false
+ }
+ }
+
+ for i, x := range h.ps {
+ if k.ps[i] != x {
+ return false
+ }
+ }
+ return true
+}
+
+/* Delve */
+
+type delveState struct {
+ cmd *exec.Cmd
+ tag string
+ *ioState
+ atLineRe *regexp.Regexp // "\n =>"
+ funcFileLinePCre *regexp.Regexp // "^> ([^ ]+) ([^:]+):([0-9]+) .*[(]PC: (0x[a-z0-9]+)"
+ line string
+ file string
+ function string
+}
+
+func newDelve(tag, executable string, args ...string) dbgr {
+ cmd := exec.Command("dlv", "exec", executable)
+ cmd.Env = replaceEnv(cmd.Env, "TERM", "dumb")
+ if len(args) > 0 {
+ cmd.Args = append(cmd.Args, "--")
+ cmd.Args = append(cmd.Args, args...)
+ }
+ s := &delveState{tag: tag, cmd: cmd}
+ // HAHA Delve has control characters embedded to change the color of the => and the line number
+ // that would be '(\\x1b\\[[0-9;]+m)?' OR TERM=dumb
+ s.atLineRe = regexp.MustCompile("\n=>[[:space:]]+[0-9]+:(.*)")
+ s.funcFileLinePCre = regexp.MustCompile("> ([^ ]+) ([^:]+):([0-9]+) .*[(]PC: (0x[a-z0-9]+)[)]\n")
+ s.ioState = newIoState(s.cmd)
+ return s
+}
+
+func (s *delveState) stepnext(ss string) bool {
+ x := s.ioState.writeReadExpect(ss+"\n", "[(]dlv[)] ")
+ excerpts := s.atLineRe.FindStringSubmatch(x.o)
+ locations := s.funcFileLinePCre.FindStringSubmatch(x.o)
+ excerpt := ""
+ if len(excerpts) > 1 {
+ excerpt = excerpts[1]
+ }
+ if len(locations) > 0 {
+ if *verbose {
+ if s.file != locations[2] {
+ fmt.Printf("%s\n", locations[2])
+ }
+ fmt.Printf(" %s\n", locations[3])
+ }
+ s.line = locations[3]
+ s.file = locations[2]
+ s.function = locations[1]
+ s.ioState.history.add(s.file, s.line, excerpt)
+ return true
+ }
+ fmt.Printf("DID NOT MATCH EXPECTED NEXT OUTPUT\nO='%s'\nE='%s'\n", x.o, x.e)
+ return false
+}
+
+func (s *delveState) start() {
+ if *dryrun {
+ fmt.Printf("%s\n", asCommandLine("", s.cmd))
+ fmt.Printf("b main.main\n")
+ fmt.Printf("c\n")
+ return
+ }
+ err := s.cmd.Start()
+ if err != nil {
+ line := asCommandLine("", s.cmd)
+ 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"))
+ s.stepnext("c")
+}
+
+func (s *delveState) quit() {
+ s.do("q")
+}
+
+func (s *delveState) do(ss string) {
+ expect("", s.ioState.writeRead(ss+"\n"))
+}
+
+/* Gdb */
+
+type gdbState struct {
+ cmd *exec.Cmd
+ tag string
+ args []string
+ *ioState
+ atLineRe *regexp.Regexp
+ funcFileLinePCre *regexp.Regexp
+ line string
+ file string
+ function string
+}
+
+func newGdb(tag, executable string, args ...string) dbgr {
+ gdb := "gdb"
+ if runtime.GOOS == "darwin" {
+ gdb = "ggdb" // A possibility on a Mac
+ }
+ cmd := exec.Command(gdb, executable)
+ cmd.Env = replaceEnv(cmd.Env, "TERM", "dumb")
+ s := &gdbState{tag: tag, cmd: cmd, args: args}
+ s.atLineRe = regexp.MustCompile("(^|\n)([0-9]+)(.*)")
+ s.funcFileLinePCre = regexp.MustCompile(
+ "([^ ]+) [(][)][ \\t\\n]+at ([^:]+):([0-9]+)")
+ // runtime.main () at /Users/drchase/GoogleDrive/work/go/src/runtime/proc.go:201
+ // function file line
+ // Thread 2 hit Breakpoint 1, main.main () at /Users/drchase/GoogleDrive/work/debug/hist.go:18
+ s.ioState = newIoState(s.cmd)
+ return s
+}
+
+func (s *gdbState) start() {
+ run := "run"
+ for _, a := range s.args {
+ run += " " + a // Can't quote args for gdb, it will pass them through including the quotes
+ }
+ if *dryrun {
+ fmt.Printf("%s\n", asCommandLine("", s.cmd))
+ fmt.Printf("b main.main\n")
+ fmt.Printf("%s\n", run)
+ return
+ }
+ err := s.cmd.Start()
+ if err != nil {
+ line := asCommandLine("", s.cmd)
+ panic(fmt.Sprintf("There was an error [start] running '%s', %v\n", line, err))
+ }
+ s.ioState.readExpecting(-1, 5000, "[(]gdb[)] ")
+ x := s.ioState.writeReadExpect("b main.main\n", "[(]gdb[)] ")
+ expect("Breakpoint [0-9]+ at", x)
+ s.stepnext(run)
+}
+
+func (s *gdbState) stepnext(ss string) bool {
+ x := s.ioState.writeReadExpect(ss+"\n", "[(]gdb[)] ")
+ excerpts := s.atLineRe.FindStringSubmatch(x.o)
+ locations := s.funcFileLinePCre.FindStringSubmatch(x.o)
+ excerpt := ""
+ if len(excerpts) == 0 && len(locations) == 0 {
+ fmt.Printf("DID NOT MATCH %s", x.o)
+ return false
+ }
+ if len(excerpts) > 0 {
+ excerpt = excerpts[3]
+ }
+ if len(locations) > 0 {
+ if *verbose {
+ if s.file != locations[2] {
+ fmt.Printf("%s\n", locations[2])
+ }
+ fmt.Printf(" %s\n", locations[3])
+ }
+ s.line = locations[3]
+ s.file = locations[2]
+ s.function = locations[1]
+ 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)
+ }
+
+ // Look for //gdb-<tag>=(v1,v2,v3) and print v1, v2, v3
+ vars := varsToPrint(excerpt, "//gdb-"+s.tag+"=(")
+ for _, v := range vars {
+ slashIndex := strings.Index(v, "/")
+ substitutions := ""
+ if slashIndex != -1 {
+ substitutions = v[slashIndex:]
+ v = v[:slashIndex]
+ }
+ response := s.ioState.writeRead("p " + v + "\n").String()
+ // expect something like "$1 = ..."
+ dollar := strings.Index(response, "$")
+ cr := strings.Index(response, "\n")
+ if dollar == -1 {
+ if cr == -1 {
+ response = strings.TrimSpace(response) // discards trailing newline
+ response = strings.Replace(response, "\n", "<BR>", -1)
+ s.ioState.history.addVar("$ Malformed response " + response)
+ continue
+ }
+ response = strings.TrimSpace(response[:cr])
+ s.ioState.history.addVar("$ " + response)
+ continue
+ }
+ if cr == -1 {
+ cr = len(response)
+ }
+ response = strings.TrimSpace(response[dollar:cr])
+ if strings.Contains(substitutions, "A") {
+ response = hexRe.ReplaceAllString(response, "<A>")
+ }
+ if strings.Contains(substitutions, "N") {
+ response = numRe.ReplaceAllString(response, "<N>")
+ }
+ if strings.Contains(substitutions, "S") {
+ response = stringRe.ReplaceAllString(response, "<S>")
+ }
+ s.ioState.history.addVar(response)
+ }
+ return true
+}
+
+func varsToPrint(line, lookfor string) []string {
+ var vars []string
+ if strings.Contains(line, lookfor) {
+ x := line[strings.Index(line, lookfor)+len(lookfor):]
+ end := strings.Index(x, ")")
+ if end == -1 {
+ panic(fmt.Sprintf("Saw variable list begin %s in %s but no closing ')'", lookfor, line))
+ }
+ vars = strings.Split(x[:end], ",")
+ for i, y := range vars {
+ vars[i] = strings.TrimSpace(y)
+ }
+ }
+ return vars
+}
+
+func (s *gdbState) quit() {
+ response := s.ioState.writeRead("q\n")
+ if strings.Contains(response.o, "Quit anyway? (y or n)") {
+ s.ioState.writeRead("Y\n")
+ }
+}
+
+func (s *gdbState) do(ss string) {
+ expect("", s.ioState.writeRead(ss+"\n"))
+}
+
+type ioState struct {
+ stdout io.ReadCloser
+ stderr io.ReadCloser
+ stdin io.WriteCloser
+ outChan chan string
+ errChan chan string
+ last tstring // Output of previous step
+ history *nextHist
+}
+
+func newIoState(cmd *exec.Cmd) *ioState {
+ var err error
+ s := &ioState{}
+ s.history = &nextHist{}
+ s.history.f2i = make(map[string]uint8)
+ s.stdout, err = cmd.StdoutPipe()
+ line := asCommandLine("", cmd)
+ if err != nil {
+ panic(fmt.Sprintf("There was an error [stdoutpipe] running '%s', %v\n", line, err))
+ }
+ s.stderr, err = cmd.StderrPipe()
+ if err != nil {
+ panic(fmt.Sprintf("There was an error [stdouterr] running '%s', %v\n", line, err))
+ }
+ s.stdin, err = cmd.StdinPipe()
+ if err != nil {
+ panic(fmt.Sprintf("There was an error [stdinpipe] running '%s', %v\n", line, err))
+ }
+
+ s.outChan = make(chan string, 1)
+ s.errChan = make(chan string, 1)
+ go func() {
+ buffer := make([]byte, 4096)
+ for {
+ n, err := s.stdout.Read(buffer)
+ if n > 0 {
+ s.outChan <- string(buffer[0:n])
+ }
+ if err == io.EOF || n == 0 {
+ break
+ }
+ if err != nil {
+ fmt.Printf("Saw an error forwarding stdout")
+ break
+ }
+ }
+ close(s.outChan)
+ s.stdout.Close()
+ }()
+
+ go func() {
+ buffer := make([]byte, 4096)
+ for {
+ n, err := s.stderr.Read(buffer)
+ if n > 0 {
+ s.errChan <- string(buffer[0:n])
+ }
+ if err == io.EOF || n == 0 {
+ break
+ }
+ if err != nil {
+ fmt.Printf("Saw an error forwarding stderr")
+ break
+ }
+ }
+ close(s.errChan)
+ s.stderr.Close()
+ }()
+ return s
+}
+
+func (s *ioState) hist() *nextHist {
+ return s.history
+}
+
+const (
+ interlineDelay = 300
+)
+
+func (s *ioState) writeRead(ss string) tstring {
+ if *verbose {
+ fmt.Printf("=> %s", ss)
+ }
+ _, err := io.WriteString(s.stdin, ss)
+ if err != nil {
+ panic(fmt.Sprintf("There was an error writing '%s', %v\n", ss, err))
+ }
+ return s.readWithDelay(-1, interlineDelay)
+}
+
+func (s *ioState) writeReadExpect(ss, expect string) tstring {
+ if *verbose {
+ fmt.Printf("=> %s", ss)
+ }
+ _, 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, "")
+}
+
+func (s *ioState) readExpecting(millis, interlineTimeout int, expected 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)
+ }
+loop:
+ for {
+ var timer <-chan time.Time
+ if timeout > 0 {
+ timer = time.After(timeout)
+ }
+ select {
+ case x, ok := <-s.outChan:
+ if !ok {
+ s.outChan = nil
+ }
+ s.last.o += x
+ case x, ok := <-s.errChan:
+ if !ok {
+ s.errChan = nil
+ }
+ s.last.e += x
+ case <-timer:
+ break loop
+ }
+ if re != nil {
+ if re.MatchString(s.last.o) {
+ break
+ }
+ if re.MatchString(s.last.e) {
+ break
+ }
+ }
+ timeout = interline
+ }
+ if *verbose {
+ fmt.Printf("<= %s%s", s.last.o, s.last.e)
+ }
+ return s.last
+}
+
+// replaceEnv returns a new environment derived from env
+// by removing any existing definition of ev and adding ev=evv.
+func replaceEnv(env []string, ev string, evv string) []string {
+ evplus := ev + "="
+ var found bool
+ for i, v := range env {
+ if strings.HasPrefix(v, evplus) {
+ found = true
+ env[i] = evplus + evv
+ }
+ }
+ if !found {
+ env = append(env, evplus+evv)
+ }
+ return env
+}
+
+// asCommandLine renders cmd as something that could be copy-and-pasted into a command line
+// If cwd is not empty and different from the command's directory, prepend an approprirate "cd"
+func asCommandLine(cwd string, cmd *exec.Cmd) string {
+ s := "("
+ if cmd.Dir != "" && cmd.Dir != cwd {
+ s += "cd" + escape(cmd.Dir) + ";"
+ }
+ for _, e := range cmd.Env {
+ if !strings.HasPrefix(e, "PATH=") &&
+ !strings.HasPrefix(e, "HOME=") &&
+ !strings.HasPrefix(e, "USER=") &&
+ !strings.HasPrefix(e, "SHELL=") {
+ s += escape(e)
+ }
+ }
+ for _, a := range cmd.Args {
+ s += escape(a)
+ }
+ s += " )"
+ return s
+}
+
+// escape inserts escapes appropriate for use in a shell command line
+func escape(s string) string {
+ s = strings.Replace(s, "\\", "\\\\", -1)
+ s = strings.Replace(s, "'", "\\'", -1)
+ // Conservative guess at characters that will force quoting
+ if strings.ContainsAny(s, "\\ ;#*&$~?!|[]()<>{}`") {
+ s = " '" + s + "'"
+ } else {
+ s = " " + s
+ }
+ return s
+}
+
+func expect(want string, got tstring) {
+ if want != "" {
+ match, err := regexp.MatchString(want, got.o)
+ if err != nil {
+ panic(fmt.Sprintf("Error for regexp %s, %v\n", want, err))
+ }
+ if match {
+ return
+ }
+ match, err = regexp.MatchString(want, got.e)
+ if match {
+ return
+ }
+ fmt.Printf("EXPECTED '%s'\n GOT O='%s'\nAND E='%s'\n", want, got.o, got.e)
+ }
+}
c = s.curBlock.NewValue1(pos, OpCopy, v.Type, s.regs[r2].c)
} else if v.rematerializeable() {
// Rematerialize instead of loading from the spill location.
- c = v.copyIntoNoXPos(s.curBlock)
+ c = v.copyIntoWithXPos(s.curBlock, pos)
} else {
// Load v from its spill location.
spill := s.makeSpill(v, s.curBlock)
// register to accomplish this.
r := e.findRegFor(v.Type)
e.erase(r)
- x = v.copyIntoNoXPos(e.p)
+ x = v.copyIntoWithXPos(e.p, pos)
e.set(r, vid, x, false, pos)
// Make sure we spill with the size of the slot, not the
// size of x (which might be wider due to our dropping
--- /dev/null
+ ./testdata/hist.go
+35: func main() {
+36: hist := make([]int, 100)
+37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
+38: if len(os.Args) > 1 {
+43: return
+47: for scanner.Scan() {
+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() {
+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() {
+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() {
+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() {
+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() {
+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() {
+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() {
+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() {
+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() {
+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() {
+57: t := 0
+58: n := 0
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+63: t += i * a
+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 {
+60: if a == 0 {
+63: t += i * a
+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 {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+63: t += i * a
+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 {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+63: t += i * a
+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 {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+68: }
+ /usr/local/google/home/drchase/work/go/src/runtime/proc.go
+201: if atomic.Load(&runningPanicDefers) != 0 {
+210: if atomic.Load(&panicking) != 0 {
+214: exit(0)
--- /dev/null
+ /usr/local/google/home/drchase/work/go/src/cmd/compile/internal/ssa/testdata/hist.go
+35: func main() {
+35: func main() {
+36: hist := make([]int, 100)
+37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
+$1 = {array = <A>, len = 100, cap = 100}
+$2 = <A> "1\n1\n1\n1\n2\n2\n2\n4\n4\n8\n"
+38: if len(os.Args) > 1 {
+43: return
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$3 = 1
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$4 = 1
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$5 = 1
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$6 = 1
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$7 = 2
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$8 = 2
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$9 = 2
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$10 = 4
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$11 = 4
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+48: s := scanner.Text()
+49: i, err := strconv.ParseInt(s, 10, 64)
+50: if err != nil { //gdb-dbg=(i)
+$12 = 8
+54: hist = ensure(int(i), hist)
+55: hist[int(i)]++
+47: for scanner.Scan() {
+57: t := 0
+58: n := 0
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+63: t += i * a
+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)
+$13 = 4
+$14 = 1
+$15 = 4
+59: for i, a := range hist {
+60: if a == 0 {
+63: t += i * a
+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)
+$16 = 7
+$17 = 2
+$18 = 10
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+63: t += i * a
+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)
+$19 = 9
+$20 = 4
+$21 = 18
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+63: t += i * a
+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)
+$22 = 10
+$23 = 8
+$24 = 26
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+60: if a == 0 {
+61: continue
+59: for i, a := range hist {
+68: }
+ /usr/local/google/home/drchase/work/go/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)
--- /dev/null
+ ./testdata/hist.go
+35: func main() {
+36: hist := make([]int, 100)
+37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
+13: "strings"
+ /usr/local/google/home/drchase/work/go/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"
+ /usr/local/google/home/drchase/work/go/src/bufio/scan.go
+84: split: ScanLines,
+74: MaxScanTokenSize = 64 * 1024
+ ./testdata/hist.go
+47: for scanner.Scan() {
+47: for scanner.Scan() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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() {
+ /usr/local/google/home/drchase/work/go/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)
+63: t += i * 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)
+63: t += i * 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 {
+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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+68: }
+ /usr/local/google/home/drchase/work/go/src/runtime/proc.go
+201: if atomic.Load(&runningPanicDefers) != 0 {
+210: if atomic.Load(&panicking) != 0 {
+214: exit(0)
--- /dev/null
+ /usr/local/google/home/drchase/work/go/src/cmd/compile/internal/ssa/testdata/hist.go
+35: func main() {
+35: func main() {
+36: hist := make([]int, 100)
+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
+47: for scanner.Scan() {
+107: return string(s.token)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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() {
+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)
+63: t += i * 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)
+63: t += i * 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 {
+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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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)
+63: t += i * 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 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+60: if a == 0 {
+68: }
+ /usr/local/google/home/drchase/work/go/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)
--- /dev/null
+// Copyright 2017 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 (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func ensure(n int, sl []int) []int {
+ for len(sl) <= n {
+ sl = append(sl, 0)
+ }
+ return sl
+}
+
+var cannedInput string = `1
+1
+1
+1
+2
+2
+2
+4
+4
+8
+`
+
+func main() {
+ hist := make([]int, 100)
+ var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
+ if len(os.Args) > 1 {
+ var err error
+ reader, err = os.Open(os.Args[1])
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "There was an error opening %s: %v\n", os.Args[1], err)
+ return
+ }
+ }
+ scanner := bufio.NewScanner(reader)
+ for scanner.Scan() {
+ s := scanner.Text()
+ i, err := strconv.ParseInt(s, 10, 64)
+ if err != nil { //gdb-dbg=(i)
+ fmt.Fprintf(os.Stderr, "There was an error: %v\n", err)
+ return
+ }
+ hist = ensure(int(i), hist)
+ hist[int(i)]++
+ }
+ t := 0
+ n := 0
+ for i, a := range hist {
+ if a == 0 {
+ continue
+ }
+ t += i * a
+ n += a
+ 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)
+ }
+
+}
// The copied value receives no source code position to avoid confusing changes
// in debugger information (the intended user is the register allocator).
func (v *Value) copyIntoNoXPos(b *Block) *Value {
- c := b.NewValue0(src.NoXPos, v.Op, v.Type) // Lose the position, this causes line number churn otherwise.
+ return v.copyIntoWithXPos(b, src.NoXPos)
+}
+
+// copyIntoWithXPos makes a new value identical to v and adds it to the end of b.
+// The supplied position is used as the position of the new value.
+func (v *Value) copyIntoWithXPos(b *Block, pos src.XPos) *Value {
+ c := b.NewValue0(pos, v.Op, v.Type)
c.Aux = v.Aux
c.AuxInt = v.AuxInt
c.AddArgs(v.Args...)