diff options
| author | Ian Lance Taylor <iant@golang.org> | 2016-05-27 16:03:44 -0700 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2016-05-31 13:02:09 +0000 |
| commit | 4223294eab3dee0f6c03fd57fc24be3dc3e2d53a (patch) | |
| tree | 70f810ef844aee4ef2a974661de8f6fb347b97df /src/cmd/internal | |
| parent | 87ee12cece96ec5837fe89c37899d725e7e852d9 (diff) | |
| download | go-4223294eab3dee0f6c03fd57fc24be3dc3e2d53a.tar.xz | |
runtime/pprof, cmd/pprof: fix profiling for PIE
In order to support pprof for position independent executables, pprof
needs to adjust the PC addresses stored in the profile by the address at
which the program is loaded. The legacy profiling support which we use
already supports recording the GNU/Linux /proc/self/maps data
immediately after the CPU samples, so do that. Also change the pprof
symbolizer to use the information, if available, when looking up
addresses in the Go pcline data.
Fixes #15714.
Change-Id: I4bf679210ef7c51d85cf873c968ce82db8898e3e
Reviewed-on: https://go-review.googlesource.com/23525
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Diffstat (limited to 'src/cmd/internal')
| -rw-r--r-- | src/cmd/internal/objfile/elf.go | 9 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/goobj.go | 4 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/macho.go | 4 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/objfile.go | 8 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/pe.go | 4 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/plan9obj.go | 4 |
6 files changed, 33 insertions, 0 deletions
diff --git a/src/cmd/internal/objfile/elf.go b/src/cmd/internal/objfile/elf.go index 3bad034097..c8114603d7 100644 --- a/src/cmd/internal/objfile/elf.go +++ b/src/cmd/internal/objfile/elf.go @@ -106,6 +106,15 @@ func (f *elfFile) goarch() string { return "" } +func (f *elfFile) loadAddress() (uint64, error) { + for _, p := range f.elf.Progs { + if p.Type == elf.PT_LOAD { + return p.Vaddr, nil + } + } + return 0, fmt.Errorf("unknown load address") +} + func (f *elfFile) dwarf() (*dwarf.Data, error) { return f.elf.DWARF() } diff --git a/src/cmd/internal/objfile/goobj.go b/src/cmd/internal/objfile/goobj.go index 5a084a94be..43435efc68 100644 --- a/src/cmd/internal/objfile/goobj.go +++ b/src/cmd/internal/objfile/goobj.go @@ -94,6 +94,10 @@ func (f *goobjFile) goarch() string { return "GOARCH unimplemented for debug/goobj files" } +func (f *goobjFile) loadAddress() (uint64, error) { + return 0, fmt.Errorf("unknown load address") +} + func (f *goobjFile) dwarf() (*dwarf.Data, error) { return nil, errors.New("no DWARF data in go object file") } diff --git a/src/cmd/internal/objfile/macho.go b/src/cmd/internal/objfile/macho.go index 754674d757..1d22a09b13 100644 --- a/src/cmd/internal/objfile/macho.go +++ b/src/cmd/internal/objfile/macho.go @@ -125,6 +125,10 @@ func (x uint64s) Len() int { return len(x) } func (x uint64s) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func (x uint64s) Less(i, j int) bool { return x[i] < x[j] } +func (f *machoFile) loadAddress() (uint64, error) { + return 0, fmt.Errorf("unknown load address") +} + func (f *machoFile) dwarf() (*dwarf.Data, error) { return f.macho.DWARF() } diff --git a/src/cmd/internal/objfile/objfile.go b/src/cmd/internal/objfile/objfile.go index 48ed9ed489..e5d99f086b 100644 --- a/src/cmd/internal/objfile/objfile.go +++ b/src/cmd/internal/objfile/objfile.go @@ -18,6 +18,7 @@ type rawFile interface { pcln() (textStart uint64, symtab, pclntab []byte, err error) text() (textStart uint64, text []byte, err error) goarch() string + loadAddress() (uint64, error) dwarf() (*dwarf.Data, error) } @@ -95,6 +96,13 @@ func (f *File) GOARCH() string { return f.raw.goarch() } +// LoadAddress returns the expected load address of the file. +// This differs from the actual load address for a position-independent +// executable. +func (f *File) LoadAddress() (uint64, error) { + return f.raw.loadAddress() +} + // DWARF returns DWARF debug data for the file, if any. // This is for cmd/pprof to locate cgo functions. func (f *File) DWARF() (*dwarf.Data, error) { diff --git a/src/cmd/internal/objfile/pe.go b/src/cmd/internal/objfile/pe.go index c024762371..46b2317242 100644 --- a/src/cmd/internal/objfile/pe.go +++ b/src/cmd/internal/objfile/pe.go @@ -199,6 +199,10 @@ func (f *peFile) goarch() string { return "" } +func (f *peFile) loadAddress() (uint64, error) { + return 0, fmt.Errorf("unknown load address") +} + func (f *peFile) dwarf() (*dwarf.Data, error) { return f.pe.DWARF() } diff --git a/src/cmd/internal/objfile/plan9obj.go b/src/cmd/internal/objfile/plan9obj.go index 6ee389dc2e..3e34f65ae7 100644 --- a/src/cmd/internal/objfile/plan9obj.go +++ b/src/cmd/internal/objfile/plan9obj.go @@ -147,6 +147,10 @@ func (f *plan9File) goarch() string { return "" } +func (f *plan9File) loadAddress() (uint64, error) { + return 0, fmt.Errorf("unknown load address") +} + func (f *plan9File) dwarf() (*dwarf.Data, error) { return nil, errors.New("no DWARF data in Plan 9 file") } |
