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 <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
}
ssaDump = os.Getenv("GOSSAFUNC")
+ ssaDir = os.Getenv("GOSSADIR")
if ssaDump != "" {
if strings.HasSuffix(ssaDump, "+") {
ssaDump = ssaDump[:len(ssaDump)-1]
"fmt"
"html"
"os"
+ "path/filepath"
"sort"
"bufio"
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"
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)
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)
}
}()
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
}
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()