From c96939fbed3d60159dc81ee9ad591de8cfd41168 Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Sun, 10 Nov 2024 12:31:16 -0800 Subject: cmd: update github.com/google/pprof dependencies Spun out of CL 626397, this change vendors in the latest github.com/google/pprof and that also required updating golang.org/x/sys to v0.27. Change-Id: I72ee514494a9e7c36a8943d78f15bdd0445c5cd5 Reviewed-on: https://go-review.googlesource.com/c/go/+/626995 TryBot-Result: Gopher Robot Reviewed-by: David Chase Run-TryBot: Emmanuel Odeke LUCI-TryBot-Result: Go LUCI Reviewed-by: Ian Lance Taylor --- .../github.com/google/pprof/driver/driver.go | 9 +- .../pprof/internal/binutils/addr2liner_llvm.go | 119 ++++++++++----------- .../google/pprof/internal/driver/config.go | 2 +- .../google/pprof/internal/driver/driver.go | 2 + .../google/pprof/internal/driver/html/common.css | 4 + .../google/pprof/internal/driver/html/header.html | 6 ++ .../google/pprof/internal/driver/html/stacks.css | 22 +++- .../google/pprof/internal/driver/html/stacks.html | 5 +- .../google/pprof/internal/driver/html/stacks.js | 72 ++++++++----- .../google/pprof/internal/driver/interactive.go | 3 + .../google/pprof/internal/driver/stacks.go | 4 +- .../google/pprof/internal/driver/webui.go | 2 + .../google/pprof/internal/elfexec/elfexec.go | 2 +- .../google/pprof/internal/plugin/plugin.go | 9 +- .../google/pprof/internal/report/report.go | 22 +++- .../google/pprof/internal/report/shortnames.go | 24 ++++- .../google/pprof/internal/report/stacks.go | 80 +++++++++----- .../google/pprof/internal/symbolizer/symbolizer.go | 1 + .../google/pprof/internal/symbolz/symbolz.go | 12 +-- .../github.com/google/pprof/profile/encode.go | 5 + .../github.com/google/pprof/profile/merge.go | 5 + .../github.com/google/pprof/profile/profile.go | 7 +- 22 files changed, 273 insertions(+), 144 deletions(-) (limited to 'src/cmd/vendor/github.com/google/pprof') diff --git a/src/cmd/vendor/github.com/google/pprof/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/driver/driver.go index 6cbf66939d..989aac32ff 100644 --- a/src/cmd/vendor/github.com/google/pprof/driver/driver.go +++ b/src/cmd/vendor/github.com/google/pprof/driver/driver.go @@ -186,10 +186,11 @@ type ObjFile interface { // A Frame describes a single line in a source file. type Frame struct { - Func string // name of function - File string // source file name - Line int // line in file - Column int // column in file + Func string // name of function + File string // source file name + Line int // line in file + Column int // column in file + StartLine int // start line of function (if available) } // A Sym describes a single symbol in an object file. diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go index 3049545b6b..2f5d97e89a 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go @@ -16,6 +16,7 @@ package binutils import ( "bufio" + "encoding/json" "fmt" "io" "os/exec" @@ -37,6 +38,7 @@ type llvmSymbolizer struct { filename string rw lineReaderWriter base uint64 + isData bool } type llvmSymbolizerJob struct { @@ -76,7 +78,7 @@ func newLLVMSymbolizer(cmd, file string, base uint64, isData bool) (*llvmSymboli } j := &llvmSymbolizerJob{ - cmd: exec.Command(cmd, "--inlining", "-demangle=false"), + cmd: exec.Command(cmd, "--inlining", "-demangle=false", "--output-style=JSON"), symType: "CODE", } if isData { @@ -102,63 +104,68 @@ func newLLVMSymbolizer(cmd, file string, base uint64, isData bool) (*llvmSymboli filename: file, rw: j, base: base, + isData: isData, } return a, nil } -// readFrame parses the llvm-symbolizer output for a single address. It -// returns a populated plugin.Frame and whether it has reached the end of the -// data. -func (d *llvmSymbolizer) readFrame() (plugin.Frame, bool) { - funcname, err := d.rw.readLine() +// readDataFrames parses the llvm-symbolizer DATA output for a single address. It +// returns a populated plugin.Frame array with a single entry. +func (d *llvmSymbolizer) readDataFrames() ([]plugin.Frame, error) { + line, err := d.rw.readLine() if err != nil { - return plugin.Frame{}, true + return nil, err } - - switch funcname { - case "": - return plugin.Frame{}, true - case "??": - funcname = "" + var frame struct { + Address string `json:"Address"` + ModuleName string `json:"ModuleName"` + Data struct { + Start string `json:"Start"` + Size string `json:"Size"` + Name string `json:"Name"` + } `json:"Data"` + } + if err := json.Unmarshal([]byte(line), &frame); err != nil { + return nil, err + } + // Match non-JSON output behaviour of stuffing the start/size into the filename of a single frame, + // with the size being a decimal value. + size, err := strconv.ParseInt(frame.Data.Size, 0, 0) + if err != nil { + return nil, err } + var stack []plugin.Frame + stack = append(stack, plugin.Frame{Func: frame.Data.Name, File: fmt.Sprintf("%s %d", frame.Data.Start, size)}) + return stack, nil +} - fileline, err := d.rw.readLine() +// readCodeFrames parses the llvm-symbolizer CODE output for a single address. It +// returns a populated plugin.Frame array. +func (d *llvmSymbolizer) readCodeFrames() ([]plugin.Frame, error) { + line, err := d.rw.readLine() if err != nil { - return plugin.Frame{Func: funcname}, true - } - - linenumber := 0 - columnnumber := 0 - // The llvm-symbolizer outputs the ::. - // When it cannot identify the source code location, it outputs "??:0:0". - // Older versions output just the filename and line number, so we check for - // both conditions here. - if fileline == "??:0" || fileline == "??:0:0" { - fileline = "" - } else { - switch split := strings.Split(fileline, ":"); len(split) { - case 3: - // filename:line:column - if col, err := strconv.Atoi(split[2]); err == nil { - columnnumber = col - } - fallthrough - case 2: - // filename:line - if line, err := strconv.Atoi(split[1]); err == nil { - linenumber = line - } - fallthrough - case 1: - // filename - fileline = split[0] - default: - // Unrecognized, ignore - } - } - - return plugin.Frame{Func: funcname, File: fileline, Line: linenumber, Column: columnnumber}, false + return nil, err + } + var frame struct { + Address string `json:"Address"` + ModuleName string `json:"ModuleName"` + Symbol []struct { + Line int `json:"Line"` + Column int `json:"Column"` + FunctionName string `json:"FunctionName"` + FileName string `json:"FileName"` + StartLine int `json:"StartLine"` + } `json:"Symbol"` + } + if err := json.Unmarshal([]byte(line), &frame); err != nil { + return nil, err + } + var stack []plugin.Frame + for _, s := range frame.Symbol { + stack = append(stack, plugin.Frame{Func: s.FunctionName, File: s.FileName, Line: s.Line, Column: s.Column, StartLine: s.StartLine}) + } + return stack, nil } // addrInfo returns the stack frame information for a specific program @@ -170,18 +177,8 @@ func (d *llvmSymbolizer) addrInfo(addr uint64) ([]plugin.Frame, error) { if err := d.rw.write(fmt.Sprintf("%s 0x%x", d.filename, addr-d.base)); err != nil { return nil, err } - - var stack []plugin.Frame - for { - frame, end := d.readFrame() - if end { - break - } - - if frame != (plugin.Frame{}) { - stack = append(stack, frame) - } + if d.isData { + return d.readDataFrames() } - - return stack, nil + return d.readCodeFrames() } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go index f7d227416e..090230e2a7 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go @@ -68,7 +68,7 @@ func defaultConfig() config { Trim: true, DivideBy: 1.0, Sort: "flat", - Granularity: "functions", + Granularity: "", // Default depends on the display format } } 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 18941926c5..99e6ba458a 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 @@ -254,6 +254,8 @@ func aggregate(prof *profile.Profile, cfg config) error { var function, filename, linenumber, address bool inlines := !cfg.NoInlines switch cfg.Granularity { + case "": + function = true // Default granularity is "functions" case "addresses": if inlines { return nil diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css index 14f836ff10..0a897ce291 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css @@ -148,6 +148,10 @@ a { right: 2px; } +.help { + padding-left: 1em; +} + {{/* Used to disable events when a modal dialog is displayed */}} #dialog-overlay { display: none; diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html index e946e6b882..5405a0be95 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html @@ -83,6 +83,12 @@ {{range .Legend}}
{{.}}
{{end}} + + {{if .DocURL}} + + {{end}}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.css b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.css index 34c54ebb49..1df4f719a5 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.css +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.css @@ -14,12 +14,26 @@ body { width: 100%; position: relative; /* Allows absolute positioning of child boxes */ } -/* Shows details of frame that is under the mouse */ +/* Holder for current frame details. */ #current-details { - position: absolute; - top: 5px; - right: 5px; + position: relative; + background: #eee; /* Light grey gives better contrast with boxes */ font-size: 12pt; + padding: 0 4px; + width: 100%; +} +/* Shows details of frame that is under the mouse */ +#current-details-left { + float: left; + max-width: 60%; + white-space: nowrap; + overflow-x: hidden; +} +#current-details-right { + float: right; + max-width: 40%; + white-space: nowrap; + overflow-x: hidden; } /* Background of a single flame-graph frame */ .boxbg { 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 c2f8cf26b1..a4e4077ed8 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 @@ -8,9 +8,12 @@ {{template "header" .}} +
+
+
 
+
-