From: David Chase Date: Mon, 31 Aug 2020 18:29:58 +0000 (-0400) Subject: cmd/compile: allow directory specification for GOSSAFUNC output X-Git-Tag: go1.16beta1~868 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f4cbf3477f1456b4d28a7b74b31820ee60b7e6d1;p=gostls13.git cmd/compile: allow directory specification for GOSSAFUNC output This was useful for debugging failures occurring during make.bash. The added flush also ensures that any hints in the GOSSAFUNC output are flushed before fatal exit. The environment variable GOSSADIR specifies where the SSA html debugging files should be placed. To avoid collisions, each one is written into the [package].[functionOrMethod].html, where [package] is the filepath separator separated package name, function is the function name, and method is either (*Type).Method, or Type.Method, as appropriate. Directories are created as necessary to make this work. Change-Id: I420927426b618b633bb1ffc51cf0f223b8f6d49c Reviewed-on: https://go-review.googlesource.com/c/go/+/252338 Trust: David Chase Run-TryBot: David Chase Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index 7ad3bfe0c8..e4e4ce72fd 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -516,6 +516,7 @@ func Main(archInit func(*Arch)) { } ssaDump = os.Getenv("GOSSAFUNC") + ssaDir = os.Getenv("GOSSADIR") if ssaDump != "" { if strings.HasSuffix(ssaDump, "+") { ssaDump = ssaDump[:len(ssaDump)-1] diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 7effa9bd4b..1d50cefe54 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -9,6 +9,7 @@ import ( "fmt" "html" "os" + "path/filepath" "sort" "bufio" @@ -26,6 +27,7 @@ var ssaConfig *ssa.Config var ssaCaches []ssa.Cache var ssaDump string // early copy of $GOSSAFUNC; the func name to dump output for +var ssaDir string // optional destination for ssa dump file var ssaDumpStdout bool // whether to dump to stdout var ssaDumpCFG string // generate CFGs for these phases const ssaDumpFile = "ssa.html" @@ -346,7 +348,13 @@ func buildssa(fn *Node, worker int) *ssa.Func { s.f.Entry.Pos = fn.Pos if printssa { - s.f.HTMLWriter = ssa.NewHTMLWriter(ssaDumpFile, s.f, ssaDumpCFG) + ssaDF := ssaDumpFile + if ssaDir != "" { + ssaDF = filepath.Join(ssaDir, myimportpath+"."+name+".html") + ssaD := filepath.Dir(ssaDF) + os.MkdirAll(ssaD, 0755) + } + s.f.HTMLWriter = ssa.NewHTMLWriter(ssaDF, s.f, ssaDumpCFG) // TODO: generate and print a mapping from nodes to values and blocks dumpSourcesColumn(s.f.HTMLWriter, fn) s.f.HTMLWriter.WriteAST("AST", astBuf) diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go index 3dec1cd85b..0664c0ba46 100644 --- a/src/cmd/compile/internal/ssa/compile.go +++ b/src/cmd/compile/internal/ssa/compile.go @@ -47,6 +47,9 @@ func Compile(f *Func) { stack := make([]byte, 16384) n := runtime.Stack(stack, false) stack = stack[:n] + if f.HTMLWriter != nil { + f.HTMLWriter.flushPhases() + } f.Fatalf("panic during %s while compiling %s:\n\n%v\n\n%s\n", phaseName, f.Name, err, stack) } }() @@ -201,6 +204,13 @@ func (p *pass) addDump(s string) { p.dump[s] = true } +func (p *pass) String() string { + if p == nil { + return "nil pass" + } + return p.name +} + // Run consistency checker between each phase var ( checkEnabled = false diff --git a/src/cmd/compile/internal/ssa/html.go b/src/cmd/compile/internal/ssa/html.go index c781ca92cc..a9d52fa4ee 100644 --- a/src/cmd/compile/internal/ssa/html.go +++ b/src/cmd/compile/internal/ssa/html.go @@ -28,18 +28,23 @@ type HTMLWriter struct { } func NewHTMLWriter(path string, f *Func, cfgMask string) *HTMLWriter { + path = strings.Replace(path, "/", string(filepath.Separator), -1) out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { f.Fatalf("%v", err) } - pwd, err := os.Getwd() - if err != nil { - f.Fatalf("%v", err) + reportPath := path + if !filepath.IsAbs(reportPath) { + pwd, err := os.Getwd() + if err != nil { + f.Fatalf("%v", err) + } + reportPath = filepath.Join(pwd, path) } html := HTMLWriter{ w: out, Func: f, - path: filepath.Join(pwd, path), + path: reportPath, dot: newDotWriter(cfgMask), } html.start()