]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/pprof: don't print binary outputs in interactive mode
authorHiroshi Ioka <hirochachacha@gmail.com>
Fri, 16 Sep 2016 07:25:48 +0000 (16:25 +0900)
committerRuss Cox <rsc@golang.org>
Fri, 11 Nov 2016 14:47:41 +0000 (14:47 +0000)
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 <rsc@golang.org>
src/cmd/pprof/internal/commands/commands.go

index 143b7c21bc8aff15b128825cdfaf4e04a3d92149..9669cb904b896919489f696c8bea579c4ec428e8 100644 (file)
@@ -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)