aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/pprof
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-11-06 19:56:55 -0500
committerRuss Cox <rsc@golang.org>2014-11-06 19:56:55 -0500
commit6bd0d0542ee15fda0da545c16af43fcfd34d6334 (patch)
tree2802dd7b5d6ee18daacc1558f7beb15dc0cfb2ed /src/cmd/pprof
parent08b2cb4afe3eebd384c543986ca8ee9d4ce04ede (diff)
downloadgo-6bd0d0542ee15fda0da545c16af43fcfd34d6334.tar.xz
cmd/objdump, cmd/pprof: factor disassembly into cmd/internal/objfile
Moving so that new Go 1.4 pprof can use it. The old 'GNU objdump workalike' mode for 'go tool objdump' is now gone, as are the tests for that mode. It was used only by pre-Go 1.4 pprof. You can still specify an address range on the command line; you just get the same output format as you do when dumping the entire binary (without an address limitation). LGTM=r R=r CC=golang-codereviews, iant https://golang.org/cl/167320043
Diffstat (limited to 'src/cmd/pprof')
-rw-r--r--src/cmd/pprof/pprof.go41
1 files changed, 38 insertions, 3 deletions
diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go
index 89a5bb7d22..44f4f6cb72 100644
--- a/src/cmd/pprof/pprof.go
+++ b/src/cmd/pprof/pprof.go
@@ -11,6 +11,7 @@ import (
"os"
"regexp"
"strings"
+ "sync"
"cmd/internal/objfile"
"cmd/pprof/internal/commands"
@@ -100,7 +101,10 @@ func (flags) ExtraUsage() string {
// objTool implements plugin.ObjTool using Go libraries
// (instead of invoking GNU binutils).
-type objTool struct{}
+type objTool struct {
+ mu sync.Mutex
+ disasmCache map[string]*objfile.Disasm
+}
func (*objTool) Open(name string, start uint64) (plugin.ObjFile, error) {
of, err := objfile.Open(name)
@@ -119,8 +123,39 @@ func (*objTool) Demangle(names []string) (map[string]string, error) {
return make(map[string]string), nil
}
-func (*objTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
- return nil, fmt.Errorf("disassembly not supported")
+func (t *objTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
+ d, err := t.cachedDisasm(file)
+ if err != nil {
+ return nil, err
+ }
+ var asm []plugin.Inst
+ d.Decode(start, end, func(pc, size uint64, file string, line int, text string) {
+ asm = append(asm, plugin.Inst{Addr: pc, File: file, Line: line, Text: text})
+ })
+ return asm, nil
+}
+
+func (t *objTool) cachedDisasm(file string) (*objfile.Disasm, error) {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ if t.disasmCache == nil {
+ t.disasmCache = make(map[string]*objfile.Disasm)
+ }
+ d := t.disasmCache[file]
+ if d != nil {
+ return d, nil
+ }
+ f, err := objfile.Open(file)
+ if err != nil {
+ return nil, err
+ }
+ d, err = f.Disasm()
+ f.Close()
+ if err != nil {
+ return nil, err
+ }
+ t.disasmCache[file] = d
+ return d, nil
}
func (*objTool) SetConfig(config string) {