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

Delta Between Two Patch Sets: src/cmd/pprof/internal/symbolz/symbolz.go

Issue 153750043: code review 153750043: cmd/pprof: add Go implementation (Closed)
Left Patch Set: Created 9 years, 6 months ago
Right Patch Set: diff -r 2e467bc60e64def06419194f48fe0d6c8b56765d https://code.google.com/p/go/ Created 9 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/pprof/internal/symbolizer/symbolizer.go ('k') | src/cmd/pprof/internal/tempfile/tempfile.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package symbolz symbolizes a profile using the output from the symbolz
6 // service.
7 package symbolz
8
9 import (
10 "bytes"
11 "fmt"
12 "io"
13 "net/url"
14 "regexp"
15 "strconv"
16 "strings"
17
18 "cmd/pprof/internal/profile"
19 )
20
21 var (
22 symbolzRE = regexp.MustCompile(`(0x[[:xdigit:]]+)\s+(.*)`)
23 )
24
25 // Symbolize symbolizes profile p by parsing data returned by a
26 // symbolz handler. syms receives the symbolz query (hex addresses
27 // separated by '+') and returns the symbolz output in a string. It
28 // symbolizes all locations based on their addresses, regardless of
29 // mapping.
30 func Symbolize(source string, syms func(string, string) ([]byte, error), p *prof ile.Profile) error {
31 if source = symbolz(source, p); source == "" {
32 // If the source is not a recognizable URL, do nothing.
33 return nil
34 }
35
36 // Construct query of addresses to symbolize.
37 var a []string
38 for _, l := range p.Location {
39 if l.Address != 0 && len(l.Line) == 0 {
40 a = append(a, fmt.Sprintf("%#x", l.Address))
41 }
42 }
43
44 if len(a) == 0 {
45 // No addresses to symbolize.
46 return nil
47 }
48 lines := make(map[uint64]profile.Line)
49 functions := make(map[string]*profile.Function)
50 if b, err := syms(source, strings.Join(a, "+")); err == nil {
51 buf := bytes.NewBuffer(b)
52 for {
53 l, err := buf.ReadString('\n')
54
55 if err != nil {
56 if err == io.EOF {
57 break
58 }
59 return err
60 }
61
62 if symbol := symbolzRE.FindStringSubmatch(l); len(symbol ) == 3 {
63 addr, err := strconv.ParseUint(symbol[1], 0, 64)
64 if err != nil {
65 return fmt.Errorf("unexpected parse fail ure %s: %v", symbol[1], err)
66 }
67
68 name := symbol[2]
69 fn := functions[name]
70 if fn == nil {
71 fn = &profile.Function{
72 ID: uint64(len(p.Functio n) + 1),
73 Name: name,
74 SystemName: name,
75 }
76 functions[name] = fn
77 p.Function = append(p.Function, fn)
78 }
79
80 lines[addr] = profile.Line{Function: fn}
81 }
82 }
83 }
84
85 for _, l := range p.Location {
86 if line, ok := lines[l.Address]; ok {
87 l.Line = []profile.Line{line}
88 if l.Mapping != nil {
89 l.Mapping.HasFunctions = true
90 }
91 }
92 }
93
94 return nil
95 }
96
97 // symbolz returns the corresponding symbolz source for a profile URL.
98 func symbolz(source string, p *profile.Profile) string {
99 if url, err := url.Parse(source); err == nil && url.Host != "" {
100 if last := strings.LastIndex(url.Path, "/"); last != -1 {
101 if strings.HasSuffix(url.Path[:last], "pprof") {
102 url.Path = url.Path[:last] + "/symbol"
103 } else {
104 url.Path = url.Path[:last] + "/symbolz"
105 }
106 return url.String()
107 }
108 }
109
110 return ""
111 }
LEFTRIGHT

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