Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(463)

Unified Diff: src/cmd/pprof/pprof.go

Issue 153750043: code review 153750043: cmd/pprof: add Go implementation (Closed)
Patch Set: diff -r 2e467bc60e64def06419194f48fe0d6c8b56765d https://code.google.com/p/go/ Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/cmd/pprof/internal/tempfile/tempfile.go ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/cmd/pprof/pprof.go
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/cmd/pprof/pprof.go
@@ -0,0 +1,202 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "debug/gosym"
+ "flag"
+ "fmt"
+ "os"
+ "regexp"
+ "strings"
+
+ "cmd/internal/objfile"
+ "cmd/pprof/internal/commands"
+ "cmd/pprof/internal/driver"
+ "cmd/pprof/internal/fetch"
+ "cmd/pprof/internal/plugin"
+ "cmd/pprof/internal/profile"
+ "cmd/pprof/internal/symbolizer"
+ "cmd/pprof/internal/symbolz"
+)
+
+func main() {
+ var extraCommands map[string]*commands.Command // no added Go-specific commands
+ if err := driver.PProf(flags{}, fetch.Fetcher, symbolize, new(objTool), plugin.StandardUI(), extraCommands); err != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", err)
+ }
+}
+
+// symbolize attempts to symbolize profile p.
+// If the source is a local binary, it tries using symbolizer and obj.
+// If the source is a URL, it fetches symbol information using symbolz.
+func symbolize(mode, source string, p *profile.Profile, obj plugin.ObjTool, ui plugin.UI) error {
+ remote, local := true, true
+ for _, o := range strings.Split(strings.ToLower(mode), ":") {
+ switch o {
+ case "none", "no":
+ return nil
+ case "local":
+ remote, local = false, true
+ case "remote":
+ remote, local = true, false
+ default:
+ ui.PrintErr("ignoring unrecognized symbolization option: " + mode)
+ ui.PrintErr("expecting -symbolize=[local|remote|none][:force]")
+ fallthrough
+ case "", "force":
+ // Ignore these options, -force is recognized by symbolizer.Symbolize
+ }
+ }
+
+ var err error
+ if local {
+ // Symbolize using binutils.
+ if err = symbolizer.Symbolize(mode, p, obj, ui); err == nil {
+ return nil
+ }
+ }
+ if remote {
+ err = symbolz.Symbolize(source, fetch.PostURL, p)
+ }
+ return err
+}
+
+// flags implements the driver.FlagPackage interface using the builtin flag package.
+type flags struct {
+}
+
+func (flags) Bool(o string, d bool, c string) *bool {
+ return flag.Bool(o, d, c)
+}
+
+func (flags) Int(o string, d int, c string) *int {
+ return flag.Int(o, d, c)
+}
+
+func (flags) Float64(o string, d float64, c string) *float64 {
+ return flag.Float64(o, d, c)
+}
+
+func (flags) String(o, d, c string) *string {
+ return flag.String(o, d, c)
+}
+
+func (flags) Parse(usage func()) []string {
+ flag.Usage = usage
+ flag.Parse()
+ args := flag.Args()
+ if len(args) == 0 {
+ usage()
+ }
+ return args
+}
+
+func (flags) ExtraUsage() string {
+ return ""
+}
+
+// objTool implements plugin.ObjTool using Go libraries
+// (instead of invoking GNU binutils).
+type objTool struct{}
+
+func (*objTool) Open(name string, start uint64) (plugin.ObjFile, error) {
+ of, err := objfile.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ f := &file{
+ name: name,
+ file: of,
+ }
+ return f, nil
+}
+
+func (*objTool) Demangle(names []string) (map[string]string, error) {
+ // No C++, nothing to demangle.
+ 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 (*objTool) SetConfig(config string) {
+ // config is usually used to say what binaries to invoke.
+ // Ignore entirely.
+}
+
+// file implements plugin.ObjFile using Go libraries
+// (instead of invoking GNU binutils).
+// A file represents a single executable being analyzed.
+type file struct {
+ name string
+ sym []objfile.Sym
+ file *objfile.File
+ pcln *gosym.Table
+}
+
+func (f *file) Name() string {
+ return f.name
+}
+
+func (f *file) Base() uint64 {
+ // No support for shared libraries.
+ return 0
+}
+
+func (f *file) BuildID() string {
+ // No support for build ID.
+ return ""
+}
+
+func (f *file) SourceLine(addr uint64) ([]plugin.Frame, error) {
+ if f.pcln == nil {
+ pcln, err := f.file.PCLineTable()
+ if err != nil {
+ return nil, err
+ }
+ f.pcln = pcln
+ }
+ file, line, fn := f.pcln.PCToLine(addr)
+ if fn == nil {
+ return nil, fmt.Errorf("no line information for PC=%#x", addr)
+ }
+ frame := []plugin.Frame{
+ {
+ Func: fn.Name,
+ File: file,
+ Line: line,
+ },
+ }
+ return frame, nil
+}
+
+func (f *file) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
+ if f.sym == nil {
+ sym, err := f.file.Symbols()
+ if err != nil {
+ return nil, err
+ }
+ f.sym = sym
+ }
+ var out []*plugin.Sym
+ for _, s := range f.sym {
+ if (r == nil || r.MatchString(s.Name)) && (addr == 0 || s.Addr <= addr && addr < s.Addr+uint64(s.Size)) {
+ out = append(out, &plugin.Sym{
+ Name: []string{s.Name},
+ File: f.name,
+ Start: s.Addr,
+ End: s.Addr + uint64(s.Size) - 1,
+ })
+ }
+ }
+ return out, nil
+}
+
+func (f *file) Close() error {
+ f.file.Close()
+ return nil
+}
« no previous file with comments | « src/cmd/pprof/internal/tempfile/tempfile.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b