From: Hiroshi Ioka Date: Fri, 16 Sep 2016 07:25:48 +0000 (+0900) Subject: cmd/pprof: don't print binary outputs in interactive mode X-Git-Tag: go1.8beta1~209 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c439a5d8b77a3b87d94bc49714faeeb2a04112f4;p=gostls13.git cmd/pprof: don't print binary outputs in interactive mode Some commands generate binary outputs which are not human readable. In interactive mode, there are no use-cases for such outputs. Instead, the new code writes it to the temporary file on the $CWD and shows the file name. So the user can use any program to display the file outside interactive shell. Fixes #17465 Change-Id: I5c479db26017607f7a28eafbff2385533e5c584e Reviewed-on: https://go-review.googlesource.com/31123 Reviewed-by: Russ Cox --- diff --git a/src/cmd/pprof/internal/commands/commands.go b/src/cmd/pprof/internal/commands/commands.go index 143b7c21bc..9669cb904b 100644 --- a/src/cmd/pprof/internal/commands/commands.go +++ b/src/cmd/pprof/internal/commands/commands.go @@ -58,26 +58,26 @@ func PProf(c Completer, interactive **bool) Commands { "peek": {c, report.Tree, nil, true, "Output callers/callees of functions matching regexp"}, // Save binary formats to a file - "callgrind": {c, report.Callgrind, awayFromTTY("callgraph.out"), false, "Outputs a graph in callgrind format"}, - "proto": {c, report.Proto, awayFromTTY("pb.gz"), false, "Outputs the profile in compressed protobuf format"}, + "callgrind": {c, report.Callgrind, awayFromTTY(interactive, "callgraph.out"), false, "Outputs a graph in callgrind format"}, + "proto": {c, report.Proto, awayFromTTY(interactive, "pb.gz"), false, "Outputs the profile in compressed protobuf format"}, // Generate report in DOT format and postprocess with dot - "gif": {c, report.Dot, invokeDot("gif"), false, "Outputs a graph image in GIF format"}, - "pdf": {c, report.Dot, invokeDot("pdf"), false, "Outputs a graph in PDF format"}, - "png": {c, report.Dot, invokeDot("png"), false, "Outputs a graph image in PNG format"}, - "ps": {c, report.Dot, invokeDot("ps"), false, "Outputs a graph in PS format"}, + "gif": {c, report.Dot, invokeDot(interactive, "gif"), false, "Outputs a graph image in GIF format"}, + "pdf": {c, report.Dot, invokeDot(interactive, "pdf"), false, "Outputs a graph in PDF format"}, + "png": {c, report.Dot, invokeDot(interactive, "png"), false, "Outputs a graph image in PNG format"}, + "ps": {c, report.Dot, invokeDot(interactive, "ps"), false, "Outputs a graph in PS format"}, // Save SVG output into a file after including svgpan library - "svg": {c, report.Dot, saveSVGToFile(), false, "Outputs a graph in SVG format"}, + "svg": {c, report.Dot, saveSVGToFile(interactive), false, "Outputs a graph in SVG format"}, // Visualize postprocessed dot output - "eog": {c, report.Dot, invokeVisualizer(interactive, invokeDot("svg"), "svg", []string{"eog"}), false, "Visualize graph through eog"}, - "evince": {c, report.Dot, invokeVisualizer(interactive, invokeDot("pdf"), "pdf", []string{"evince"}), false, "Visualize graph through evince"}, - "gv": {c, report.Dot, invokeVisualizer(interactive, invokeDot("ps"), "ps", []string{"gv --noantialias"}), false, "Visualize graph through gv"}, - "web": {c, report.Dot, invokeVisualizer(interactive, saveSVGToFile(), "svg", browsers()), false, "Visualize graph through web browser"}, + "eog": {c, report.Dot, invokeVisualizer(interactive, invokeDot(nil, "svg"), "svg", []string{"eog"}), false, "Visualize graph through eog"}, + "evince": {c, report.Dot, invokeVisualizer(interactive, invokeDot(nil, "pdf"), "pdf", []string{"evince"}), false, "Visualize graph through evince"}, + "gv": {c, report.Dot, invokeVisualizer(interactive, invokeDot(nil, "ps"), "ps", []string{"gv --noantialias"}), false, "Visualize graph through gv"}, + "web": {c, report.Dot, invokeVisualizer(interactive, saveSVGToFile(nil), "svg", browsers()), false, "Visualize graph through web browser"}, // Visualize HTML directly generated by report. - "weblist": {c, report.WebList, invokeVisualizer(interactive, awayFromTTY("html"), "html", browsers()), true, "Output annotated source in HTML for functions matching regexp or address"}, + "weblist": {c, report.WebList, invokeVisualizer(interactive, awayFromTTY(nil, "html"), "html", browsers()), true, "Output annotated source in HTML for functions matching regexp or address"}, } } @@ -133,9 +133,9 @@ func NewCompleter(cs Commands) Completer { // awayFromTTY saves the output in a file if it would otherwise go to // the terminal screen. This is used to avoid dumping binary data on // the screen. -func awayFromTTY(format string) PostProcessor { +func awayFromTTY(interactive **bool, format string) PostProcessor { return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error { - if output == os.Stdout && ui.IsTerminal() { + if output == os.Stdout && (ui.IsTerminal() || interactive != nil && **interactive) { tempFile, err := tempfile.New("", "profile", "."+format) if err != nil { return err @@ -149,8 +149,8 @@ func awayFromTTY(format string) PostProcessor { } } -func invokeDot(format string) PostProcessor { - divert := awayFromTTY(format) +func invokeDot(interactive **bool, format string) PostProcessor { + divert := awayFromTTY(interactive, format) return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error { if _, err := exec.LookPath("dot"); err != nil { ui.PrintErr("Cannot find dot, have you installed Graphviz?") @@ -166,9 +166,9 @@ func invokeDot(format string) PostProcessor { } } -func saveSVGToFile() PostProcessor { - generateSVG := invokeDot("svg") - divert := awayFromTTY("svg") +func saveSVGToFile(interactive **bool) PostProcessor { + generateSVG := invokeDot(nil, "svg") + divert := awayFromTTY(interactive, "svg") return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error { baseSVG := &bytes.Buffer{} generateSVG(input, baseSVG, ui)