aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vendor/github.com/google/pprof/internal/driver
diff options
context:
space:
mode:
authorEmmanuel T Odeke <emmanuel@orijtech.com>2024-05-27 21:07:22 -0600
committerGopher Robot <gobot@golang.org>2024-05-31 19:48:28 +0000
commit9b43bfbc51c469ec13fca24960834a75b2bf66eb (patch)
treecafe177d5e024ae1a903f9c69824ed99ee673082 /src/cmd/vendor/github.com/google/pprof/internal/driver
parent00b8071a12e298303b2f4bd0e9f641ef3e54772a (diff)
downloadgo-9b43bfbc51c469ec13fca24960834a75b2bf66eb.tar.xz
cmd/vendor: update github.com/google/pprof
Brings in the latest github.com/google/pprof. Fixes #67626 Change-Id: Id8faef20f0a9bf81dd117110bf540aca852db6be Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest Reviewed-on: https://go-review.googlesource.com/c/go/+/588655 Reviewed-by: Carlos Amedee <carlos@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Diffstat (limited to 'src/cmd/vendor/github.com/google/pprof/internal/driver')
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go22
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.css7
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html1
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html70
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html1
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js60
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go6
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go20
-rw-r--r--src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go32
11 files changed, 163 insertions, 60 deletions
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
index 74ce8cb422..18941926c5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
@@ -20,6 +20,7 @@ package driver
import (
"bytes"
"fmt"
+ "io"
"os"
"path/filepath"
"regexp"
@@ -118,7 +119,14 @@ func generateReport(p *profile.Profile, cmd []string, cfg config, o *plugin.Opti
// Generate the report.
dst := new(bytes.Buffer)
- if err := report.Generate(dst, rpt, o.Obj); err != nil {
+ switch rpt.OutputFormat() {
+ case report.WebList:
+ // We need template expansion, so generate here instead of in report.
+ err = printWebList(dst, rpt, o.Obj)
+ default:
+ err = report.Generate(dst, rpt, o.Obj)
+ }
+ if err != nil {
return err
}
src := dst
@@ -155,6 +163,18 @@ func generateReport(p *profile.Profile, cmd []string, cfg config, o *plugin.Opti
return out.Close()
}
+func printWebList(dst io.Writer, rpt *report.Report, obj plugin.ObjTool) error {
+ listing, err := report.MakeWebList(rpt, obj, -1)
+ if err != nil {
+ return err
+ }
+ legend := report.ProfileLabels(rpt)
+ return renderHTML(dst, "sourcelisting", rpt, nil, legend, webArgs{
+ Standalone: true,
+ Listing: listing,
+ })
+}
+
func applyCommandOverrides(cmd string, outputFormat int, cfg config) config {
// Some report types override the trim flag to false below. This is to make
// sure the default heuristics of excluding insignificant nodes and edges
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
index 95204a394f..a94ddf6adb 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
@@ -493,7 +493,7 @@ func fetch(source string, duration, timeout time.Duration, ui plugin.UI, tr http
var f io.ReadCloser
// First determine whether the source is a file, if not, it will be treated as a URL.
- if _, openErr := os.Stat(source); openErr == nil {
+ if _, err = os.Stat(source); err == nil {
if isPerfFile(source) {
f, err = convertPerfData(source, ui)
} else {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.css b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.css
new file mode 100644
index 0000000000..c756ddfdcb
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.css
@@ -0,0 +1,7 @@
+#graph {
+ cursor: grab;
+}
+
+#graph:active {
+ cursor: grabbing;
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html
index a113549fc4..d17a0ea7d0 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/graph.html
@@ -4,6 +4,7 @@
<meta charset="utf-8">
<title>{{.Title}}</title>
{{template "css" .}}
+ {{template "graph_css" .}}
</head>
<body>
{{template "header" .}}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html
index 3212bee4a0..b676ce2054 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/source.html
@@ -3,16 +3,70 @@
<head>
<meta charset="utf-8">
<title>{{.Title}}</title>
- {{template "css" .}}
+ {{if not .Standalone}}{{template "css" .}}{{end}}
{{template "weblistcss" .}}
{{template "weblistjs" .}}
</head>
-<body>
- {{template "header" .}}
- <div id="content" class="source">
- {{.HTMLBody}}
- </div>
- {{template "script" .}}
- <script>viewer(new URL(window.location.href), null);</script>
+<body>{{"\n" -}}
+ {{/* emit different header in standalone mode */ -}}
+ {{if .Standalone}}{{"\n" -}}
+ <div class="legend">{{"" -}}
+ {{range $i, $e := .Legend -}}
+ {{if $i}}<br>{{"\n"}}{{end}}{{. -}}
+ {{end}}<br>Total: {{.Listing.Total -}}
+ </div>{{"" -}}
+ {{else -}}
+ {{template "header" .}}
+ <div id="content" class="source">{{"" -}}
+ {{end -}}
+
+ {{range .Listing.Files -}}
+ {{range .Funcs -}}
+ <h2>{{.Name}}</h2>{{"" -}}
+ <p class="filename">{{.File}}</p>{{"\n" -}}
+ <pre onClick="pprof_toggle_asm(event)">{{"\n" -}}
+ {{printf " Total: %10s %10s (flat, cum) %s" .Flat .Cumulative .Percent -}}
+ {{range .Lines -}}{{"\n" -}}
+ {{/* source line */ -}}
+ <span class=line>{{printf " %6d" .Line}}</span>{{" " -}}
+ <span class={{.HTMLClass}}>
+ {{- printf " %10s %10s %8s %s " .Flat .Cumulative "" .SrcLine -}}
+ </span>{{"" -}}
+
+ {{if .Instructions -}}
+ {{/* instructions for this source line */ -}}
+ <span class=asm>{{"" -}}
+ {{range .Instructions -}}
+ {{/* separate when we hit a new basic block */ -}}
+ {{if .NewBlock -}}{{printf " %8s %28s\n" "" "⋮"}}{{end -}}
+
+ {{/* inlined calls leading to this instruction */ -}}
+ {{range .InlinedCalls -}}
+ {{printf " %8s %10s %10s %8s " "" "" "" "" -}}
+ <span class=inlinesrc>{{.SrcLine}}</span>{{" " -}}
+ <span class=unimportant>{{.FileBase}}:{{.Line}}</span>{{"\n" -}}
+ {{end -}}
+
+ {{if not .Synthetic -}}
+ {{/* disassembled instruction */ -}}
+ {{printf " %8s %10s %10s %8x: %s " "" .Flat .Cumulative .Address .Disasm -}}
+ <span class=unimportant>{{.FileLine}}</span>{{"\n" -}}
+ {{end -}}
+ {{end -}}
+ </span>{{"" -}}
+ {{end -}}
+ {{/* end of line */ -}}
+ {{end}}{{"\n" -}}
+ </pre>{{"\n" -}}
+ {{/* end of function */ -}}
+ {{end -}}
+ {{/* end of file */ -}}
+ {{end -}}
+
+ {{if not .Standalone}}{{"\n " -}}
+ </div>{{"\n" -}}
+ {{template "script" .}}{{"\n" -}}
+ <script>viewer(new URL(window.location.href), null);</script>{{"" -}}
+ {{end}}
</body>
</html>
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html
index 1ddb7a3a1c..c2f8cf26b1 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html
@@ -26,6 +26,7 @@
{{template "script" .}}
{{template "stacks_js"}}
<script>
+ pprofUnitDefs = {{.UnitDefs}};
stackViewer({{.Stacks}}, {{.Nodes}});
</script>
</body>
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js
index c8059fe6bf..df0f0649b9 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js
@@ -13,23 +13,6 @@ function stackViewer(stacks, nodes) {
const FONT_SIZE = 12;
const MIN_FONT_SIZE = 8;
- // Mapping from unit to a list of display scales/labels.
- // List should be ordered by increasing unit size.
- const UNITS = new Map([
- ['B', [
- ['B', 1],
- ['kB', Math.pow(2, 10)],
- ['MB', Math.pow(2, 20)],
- ['GB', Math.pow(2, 30)],
- ['TB', Math.pow(2, 40)],
- ['PB', Math.pow(2, 50)]]],
- ['s', [
- ['ns', 1e-9],
- ['µs', 1e-6],
- ['ms', 1e-3],
- ['s', 1],
- ['hrs', 60*60]]]]);
-
// Fields
let pivots = []; // Indices of currently selected data.Sources entries.
let matches = new Set(); // Indices of sources that match search
@@ -570,22 +553,7 @@ function stackViewer(stacks, nodes) {
// unitText returns a formatted string to display for value.
function unitText(value) {
- const sign = (value < 0) ? "-" : "";
- let v = Math.abs(value) * stacks.Scale;
- // Rescale to appropriate display unit.
- let unit = stacks.Unit;
- const list = UNITS.get(unit);
- if (list) {
- // Find first entry in list that is not too small.
- for (const [name, scale] of list) {
- if (v <= 100*scale) {
- v /= scale;
- unit = name;
- break;
- }
- }
- }
- return sign + Number(v.toFixed(2)) + unit;
+ return pprofUnitText(value*stacks.Scale, stacks.Unit);
}
function find(name) {
@@ -606,3 +574,29 @@ function stackViewer(stacks, nodes) {
return hsl;
}
}
+
+// pprofUnitText returns a formatted string to display for value in the specified unit.
+function pprofUnitText(value, unit) {
+ const sign = (value < 0) ? "-" : "";
+ let v = Math.abs(value);
+ // Rescale to appropriate display unit.
+ let list = null;
+ for (const def of pprofUnitDefs) {
+ if (def.DefaultUnit.CanonicalName == unit) {
+ list = def.Units;
+ v *= def.DefaultUnit.Factor;
+ break;
+ }
+ }
+ if (list) {
+ // Stop just before entry that is too large.
+ for (let i = 0; i < list.length; i++) {
+ if (i == list.length-1 || list[i+1].Factor > v) {
+ v /= list[i].Factor;
+ unit = list[i].CanonicalName;
+ break;
+ }
+ }
+ }
+ return sign + Number(v.toFixed(2)) + unit;
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go
index b784618aca..5011a06666 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go
@@ -102,7 +102,7 @@ func configMenu(fname string, u url.URL) []configMenuEntry {
UserConfig: (i != 0),
}
}
- // Mark the last matching config as currennt
+ // Mark the last matching config as current
if lastMatch >= 0 {
result[lastMatch].Current = true
}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go
index 6a61613344..355b8f2e2a 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go
@@ -19,6 +19,7 @@ import (
"html/template"
"net/http"
+ "github.com/google/pprof/internal/measurement"
"github.com/google/pprof/internal/report"
)
@@ -52,7 +53,8 @@ func (ui *webInterface) stackView(w http.ResponseWriter, req *http.Request) {
_, legend := report.TextItems(rpt)
ui.render(w, req, "stacks", rpt, errList, legend, webArgs{
- Stacks: template.JS(b),
- Nodes: nodes,
+ Stacks: template.JS(b),
+ Nodes: nodes,
+ UnitDefs: measurement.UnitTypes,
})
}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
index 984936a9d6..0b8630bcf1 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
@@ -19,8 +19,27 @@ import (
"fmt"
"html/template"
"os"
+ "sync"
+
+ "github.com/google/pprof/internal/report"
+)
+
+var (
+ htmlTemplates *template.Template // Lazily loaded templates
+ htmlTemplateInit sync.Once
)
+// getHTMLTemplates returns the set of HTML templates used by pprof,
+// initializing them if necessary.
+func getHTMLTemplates() *template.Template {
+ htmlTemplateInit.Do(func() {
+ htmlTemplates = template.New("templategroup")
+ addTemplates(htmlTemplates)
+ report.AddSourceTemplates(htmlTemplates)
+ })
+ return htmlTemplates
+}
+
//go:embed html
var embeddedFiles embed.FS
@@ -54,6 +73,7 @@ func addTemplates(templates *template.Template) {
def("css", loadCSS("html/common.css"))
def("header", loadFile("html/header.html"))
def("graph", loadFile("html/graph.html"))
+ def("graph_css", loadCSS("html/graph.css"))
def("script", loadJS("html/common.js"))
def("top", loadFile("html/top.html"))
def("sourcelisting", loadFile("html/source.html"))
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
index 476e1d2cdf..2a2d7fb1d2 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
@@ -18,6 +18,7 @@ import (
"bytes"
"fmt"
"html/template"
+ "io"
"net"
"net/http"
gourl "net/url"
@@ -28,6 +29,7 @@ import (
"time"
"github.com/google/pprof/internal/graph"
+ "github.com/google/pprof/internal/measurement"
"github.com/google/pprof/internal/plugin"
"github.com/google/pprof/internal/report"
"github.com/google/pprof/profile"
@@ -39,7 +41,6 @@ type webInterface struct {
copier profileCopier
options *plugin.Options
help map[string]string
- templates *template.Template
settingsFile string
}
@@ -48,15 +49,11 @@ func makeWebInterface(p *profile.Profile, copier profileCopier, opt *plugin.Opti
if err != nil {
return nil, err
}
- templates := template.New("templategroup")
- addTemplates(templates)
- report.AddSourceTemplates(templates)
return &webInterface{
prof: p,
copier: copier,
options: opt,
help: make(map[string]string),
- templates: templates,
settingsFile: settingsFile,
}, nil
}
@@ -82,14 +79,17 @@ type webArgs struct {
Total int64
SampleTypes []string
Legend []string
+ Standalone bool // True for command-line generation of HTML
Help map[string]string
Nodes []string
HTMLBody template.HTML
TextBody string
Top []report.TextItem
+ Listing report.WebListData
FlameGraph template.JS
Stacks template.JS
Configs []configMenuEntry
+ UnitDefs []measurement.UnitType
}
func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, disableBrowser bool) error {
@@ -283,21 +283,25 @@ func (ui *webInterface) makeReport(w http.ResponseWriter, req *http.Request,
return rpt, catcher.errors
}
-// render generates html using the named template based on the contents of data.
-func (ui *webInterface) render(w http.ResponseWriter, req *http.Request, tmpl string,
- rpt *report.Report, errList, legend []string, data webArgs) {
+// renderHTML generates html using the named template based on the contents of data.
+func renderHTML(dst io.Writer, tmpl string, rpt *report.Report, errList, legend []string, data webArgs) error {
file := getFromLegend(legend, "File: ", "unknown")
profile := getFromLegend(legend, "Type: ", "unknown")
data.Title = file + " " + profile
data.Errors = errList
data.Total = rpt.Total()
- data.SampleTypes = sampleTypes(ui.prof)
data.Legend = legend
+ return getHTMLTemplates().ExecuteTemplate(dst, tmpl, data)
+}
+
+// render responds with html generated by passing data to the named template.
+func (ui *webInterface) render(w http.ResponseWriter, req *http.Request, tmpl string,
+ rpt *report.Report, errList, legend []string, data webArgs) {
+ data.SampleTypes = sampleTypes(ui.prof)
data.Help = ui.help
data.Configs = configMenu(ui.settingsFile, *req.URL)
-
html := &bytes.Buffer{}
- if err := ui.templates.ExecuteTemplate(html, tmpl, data); err != nil {
+ if err := renderHTML(html, tmpl, rpt, errList, legend, data); err != nil {
http.Error(w, "internal template error", http.StatusInternalServerError)
ui.options.UI.PrintErr(err)
return
@@ -410,8 +414,8 @@ func (ui *webInterface) source(w http.ResponseWriter, req *http.Request) {
}
// Generate source listing.
- var body bytes.Buffer
- if err := report.PrintWebList(&body, rpt, ui.options.Obj, maxEntries); err != nil {
+ listing, err := report.MakeWebList(rpt, ui.options.Obj, maxEntries)
+ if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
ui.options.UI.PrintErr(err)
return
@@ -419,7 +423,7 @@ func (ui *webInterface) source(w http.ResponseWriter, req *http.Request) {
legend := report.ProfileLabels(rpt)
ui.render(w, req, "sourcelisting", rpt, errList, legend, webArgs{
- HTMLBody: template.HTML(body.String()),
+ Listing: listing,
})
}