diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index ce1a32f386..c99cb8cdb3 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -3,7 +3,7 @@ module cmd
go 1.19
require (
- github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31
+ github.com/google/pprof v0.0.0-20220314021825-5bba342933ea
golang.org/x/arch v0.0.0-20210923205945-b76863e36670
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index b4a800b07e..39d9e109ad 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -1,8 +1,8 @@
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31 h1:YvpxjnjGhf/vDEeYOysNbsrtB///PKS8lqkFNSDm1p8=
-github.com/google/pprof v0.0.0-20211104044539-f987b9c94b31/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
+github.com/google/pprof v0.0.0-20220314021825-5bba342933ea h1:yVDp4C9ff/qoEAhHNf5cqk/YTxTGECSzGYzahdhEKBI=
+github.com/google/pprof v0.0.0-20220314021825-5bba342933ea/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d h1:uGg2frlt3IcT7kbV6LEp5ONv4vmoO2FW4qSO+my/aoM=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go
index e72c765adc..c073c964b4 100644
--- a/src/cmd/pprof/pprof.go
+++ b/src/cmd/pprof/pprof.go
@@ -149,7 +149,7 @@ type objTool struct {
disasmCache map[string]*objfile.Disasm
}
-func (*objTool) Open(name string, start, limit, offset uint64) (driver.ObjFile, error) {
+func (*objTool) Open(name string, start, limit, offset uint64, relocationSymbol string) (driver.ObjFile, error) {
of, err := objfile.Open(name)
if err != nil {
return nil, err
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 fc05f919ba..5a8222f70a 100644
--- a/src/cmd/vendor/github.com/google/pprof/driver/driver.go
+++ b/src/cmd/vendor/github.com/google/pprof/driver/driver.go
@@ -137,8 +137,10 @@ type MappingSources map[string][]struct {
type ObjTool interface {
// Open opens the named object file. If the object is a shared
// library, start/limit/offset are the addresses where it is mapped
- // into memory in the address space being inspected.
- Open(file string, start, limit, offset uint64) (ObjFile, error)
+ // into memory in the address space being inspected. If the object
+ // is a linux kernel, relocationSymbol is the name of the symbol
+ // corresponding to the start address.
+ Open(file string, start, limit, offset uint64, relocationSymbol string) (ObjFile, error)
// Disasm disassembles the named object file, starting at
// the start address and stopping at (before) the end address.
@@ -232,8 +234,8 @@ type internalObjTool struct {
ObjTool
}
-func (o *internalObjTool) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) {
- f, err := o.ObjTool.Open(file, start, limit, offset)
+func (o *internalObjTool) Open(file string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) {
+ f, err := o.ObjTool.Open(file, start, limit, offset, relocationSymbol)
if err != nil {
return nil, err
}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
index e920eeb2fa..efa9167af7 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils.go
@@ -284,7 +284,7 @@ func (bu *Binutils) Disasm(file string, start, end uint64, intelSyntax bool) ([]
}
// Open satisfies the plugin.ObjTool interface.
-func (bu *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
+func (bu *Binutils) Open(name string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) {
b := bu.get()
// Make sure file is a supported executable.
@@ -316,7 +316,7 @@ func (bu *Binutils) Open(name string, start, limit, offset uint64) (plugin.ObjFi
// Match against supported file types.
if elfMagic == elf.ELFMAG {
- f, err := b.openELF(name, start, limit, offset)
+ f, err := b.openELF(name, start, limit, offset, relocationSymbol)
if err != nil {
return nil, fmt.Errorf("error reading ELF file %s: %v", name, err)
}
@@ -425,7 +425,7 @@ func (b *binrep) openMachO(name string, start, limit, offset uint64) (plugin.Obj
return b.openMachOCommon(name, of, start, limit, offset)
}
-func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFile, error) {
+func (b *binrep) openELF(name string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) {
ef, err := elfOpen(name)
if err != nil {
return nil, fmt.Errorf("error parsing %s: %v", name, err)
@@ -440,8 +440,8 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi
}
var (
- stextOffset *uint64
- pageAligned = func(addr uint64) bool { return addr%4096 == 0 }
+ kernelOffset *uint64
+ pageAligned = func(addr uint64) bool { return addr%4096 == 0 }
)
if strings.Contains(name, "vmlinux") || !pageAligned(start) || !pageAligned(limit) || !pageAligned(offset) {
// Reading all Symbols is expensive, and we only rarely need it so
@@ -455,10 +455,18 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi
if err != nil && err != elf.ErrNoSymbols {
return nil, err
}
+
+ // The kernel relocation symbol (the mapping start address) can be either
+ // _text or _stext. When profiles are generated by `perf`, which one was used is
+ // distinguished by the mapping name for the kernel image:
+ // '[kernel.kallsyms]_text' or '[kernel.kallsyms]_stext', respectively. If we haven't
+ // been able to parse it from the mapping, we default to _stext.
+ if relocationSymbol == "" {
+ relocationSymbol = "_stext"
+ }
for _, s := range symbols {
- if s.Name == "_stext" {
- // The kernel may use _stext as the mapping start address.
- stextOffset = &s.Value
+ if s.Name == relocationSymbol {
+ kernelOffset = &s.Value
break
}
}
@@ -469,7 +477,7 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi
// value until we have a sample address for this mapping, so that we can
// correctly identify the associated program segment that is needed to compute
// the base.
- if _, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), stextOffset, start, limit, offset); err != nil {
+ if _, err := elfexec.GetBase(&ef.FileHeader, elfexec.FindTextProgHeader(ef), kernelOffset, start, limit, offset); err != nil {
return nil, fmt.Errorf("could not identify base for %s: %v", name, err)
}
@@ -478,14 +486,14 @@ func (b *binrep) openELF(name string, start, limit, offset uint64) (plugin.ObjFi
b: b,
name: name,
buildID: buildID,
- m: &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset},
+ m: &elfMapping{start: start, limit: limit, offset: offset, kernelOffset: kernelOffset},
}}, nil
}
return &fileAddr2Line{file: file{
b: b,
name: name,
buildID: buildID,
- m: &elfMapping{start: start, limit: limit, offset: offset, stextOffset: stextOffset},
+ m: &elfMapping{start: start, limit: limit, offset: offset, kernelOffset: kernelOffset},
}}, nil
}
@@ -521,8 +529,8 @@ func (b *binrep) openPE(name string, start, limit, offset uint64) (plugin.ObjFil
type elfMapping struct {
// Runtime mapping parameters.
start, limit, offset uint64
- // Offset of _stext symbol. Only defined for kernel images, nil otherwise.
- stextOffset *uint64
+ // Offset of kernel relocation symbol. Only defined for kernel images, nil otherwise.
+ kernelOffset *uint64
}
// findProgramHeader returns the program segment that matches the current
@@ -535,7 +543,7 @@ func (m *elfMapping) findProgramHeader(ef *elf.File, addr uint64) (*elf.ProgHead
// it's a kernel / .ko module mapping, because with quipper address remapping
// enabled, the address would be in the lower half of the address space.
- if m.stextOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) {
+ if m.kernelOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) {
// For the kernel, find the program segment that includes the .text section.
return elfexec.FindTextProgHeader(ef), nil
}
@@ -601,7 +609,7 @@ func (f *file) computeBase(addr uint64) error {
return fmt.Errorf("failed to find program header for file %q, ELF mapping %#v, address %x: %v", f.name, *f.m, addr, err)
}
- base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.stextOffset, f.m.start, f.m.limit, f.m.offset)
+ base, err := elfexec.GetBase(&ef.FileHeader, ph, f.m.kernelOffset, f.m.start, f.m.limit, f.m.offset)
if err != nil {
return err
}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
index 492400c5f3..237cc33233 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
@@ -98,7 +98,7 @@ func parseFlags(o *plugin.Options) (*source, []string, error) {
// Recognize first argument as an executable or buildid override.
if len(args) > 1 {
arg0 := args[0]
- if file, err := o.Obj.Open(arg0, 0, ^uint64(0), 0); err == nil {
+ if file, err := o.Obj.Open(arg0, 0, ^uint64(0), 0, ""); err == nil {
file.Close()
execName = arg0
args = args[1:]
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 b8a69e87fc..0b361651bc 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
@@ -420,12 +420,14 @@ mapping:
fileNames = append(fileNames, filepath.Join(path, m.File))
}
for _, name := range fileNames {
- if f, err := obj.Open(name, m.Start, m.Limit, m.Offset); err == nil {
+ if f, err := obj.Open(name, m.Start, m.Limit, m.Offset, m.KernelRelocationSymbol); err == nil {
defer f.Close()
fileBuildID := f.BuildID()
if m.BuildID != "" && m.BuildID != fileBuildID {
ui.PrintErr("Ignoring local file " + name + ": build-id mismatch (" + m.BuildID + " != " + fileBuildID + ")")
} else {
+ // Explicitly do not update KernelRelocationSymbol --
+ // the new local file name is most likely missing it.
m.File = name
continue mapping
}
@@ -449,6 +451,8 @@ mapping:
if execName, buildID := s.ExecName, s.BuildID; execName != "" || buildID != "" {
m := p.Mapping[0]
if execName != "" {
+ // Explicitly do not update KernelRelocationSymbol --
+ // the source override is most likely missing it.
m.File = execName
}
if buildID != "" {
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 b9c73271b8..63df668321 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
@@ -17,13 +17,11 @@ package driver
import (
"html/template"
- "github.com/google/pprof/third_party/d3"
"github.com/google/pprof/third_party/d3flamegraph"
)
// addTemplates adds a set of template definitions to templates.
func addTemplates(templates *template.Template) {
- template.Must(templates.Parse(`{{define "d3script"}}` + d3.JSSource + `{{end}}`))
template.Must(templates.Parse(`{{define "d3flamegraphscript"}}` + d3flamegraph.JSSource + `{{end}}`))
template.Must(templates.Parse(`{{define "d3flamegraphcss"}}` + d3flamegraph.CSSSource + `{{end}}`))
template.Must(templates.Parse(`
@@ -1329,40 +1327,29 @@ function viewer(baseUrl, nodes) {
{{template "script" .}}
-