1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package profile
18
19 import (
20 "fmt"
21 "regexp"
22 "strings"
23 )
24
25 var (
26 reservedNames = []string{"(anonymous namespace)", "operator()"}
27 bracketRx = func() *regexp.Regexp {
28 var quotedNames []string
29 for _, name := range append(reservedNames, "(") {
30 quotedNames = append(quotedNames, regexp.QuoteMeta(name))
31 }
32 return regexp.MustCompile(strings.Join(quotedNames, "|"))
33 }()
34 )
35
36
37 func simplifyFunc(f string) string {
38
39 funcName := strings.TrimPrefix(f, ".")
40
41
42 for _, ind := range bracketRx.FindAllStringSubmatchIndex(funcName, -1) {
43 foundReserved := false
44 for _, res := range reservedNames {
45 if funcName[ind[0]:ind[1]] == res {
46 foundReserved = true
47 break
48 }
49 }
50 if !foundReserved {
51 funcName = funcName[:ind[0]]
52 break
53 }
54 }
55 return funcName
56 }
57
58
59
60
61 func (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) {
62 prune := make(map[uint64]bool)
63 pruneBeneath := make(map[uint64]bool)
64
65
66
67
68 pruneCache := map[string]bool{}
69 pruneFromHere := func(s string) bool {
70 if r, ok := pruneCache[s]; ok {
71 return r
72 }
73 funcName := simplifyFunc(s)
74 if dropRx.MatchString(funcName) {
75 if keepRx == nil || !keepRx.MatchString(funcName) {
76 pruneCache[s] = true
77 return true
78 }
79 }
80 pruneCache[s] = false
81 return false
82 }
83
84 for _, loc := range p.Location {
85 var i int
86 for i = len(loc.Line) - 1; i >= 0; i-- {
87 if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
88 if pruneFromHere(fn.Name) {
89 break
90 }
91 }
92 }
93
94 if i >= 0 {
95
96 pruneBeneath[loc.ID] = true
97
98
99 if i == len(loc.Line)-1 {
100
101 prune[loc.ID] = true
102 } else {
103 loc.Line = loc.Line[i+1:]
104 }
105 }
106 }
107
108
109 for _, sample := range p.Sample {
110
111
112
113 foundUser := false
114 for i := len(sample.Location) - 1; i >= 0; i-- {
115 id := sample.Location[i].ID
116 if !prune[id] && !pruneBeneath[id] {
117 foundUser = true
118 continue
119 }
120 if !foundUser {
121 continue
122 }
123 if prune[id] {
124 sample.Location = sample.Location[i+1:]
125 break
126 }
127 if pruneBeneath[id] {
128 sample.Location = sample.Location[i:]
129 break
130 }
131 }
132 }
133 }
134
135
136
137 func (p *Profile) RemoveUninteresting() error {
138 var keep, drop *regexp.Regexp
139 var err error
140
141 if p.DropFrames != "" {
142 if drop, err = regexp.Compile("^(" + p.DropFrames + ")$"); err != nil {
143 return fmt.Errorf("failed to compile regexp %s: %v", p.DropFrames, err)
144 }
145 if p.KeepFrames != "" {
146 if keep, err = regexp.Compile("^(" + p.KeepFrames + ")$"); err != nil {
147 return fmt.Errorf("failed to compile regexp %s: %v", p.KeepFrames, err)
148 }
149 }
150 p.Prune(drop, keep)
151 }
152 return nil
153 }
154
155
156
157
158
159
160
161
162
163
164
165
166
167 func (p *Profile) PruneFrom(dropRx *regexp.Regexp) {
168 pruneBeneath := make(map[uint64]bool)
169
170 for _, loc := range p.Location {
171 for i := 0; i < len(loc.Line); i++ {
172 if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
173 funcName := simplifyFunc(fn.Name)
174 if dropRx.MatchString(funcName) {
175
176 pruneBeneath[loc.ID] = true
177 loc.Line = loc.Line[i:]
178 break
179 }
180 }
181 }
182 }
183
184
185 for _, sample := range p.Sample {
186
187 for i, loc := range sample.Location {
188 if pruneBeneath[loc.ID] {
189 sample.Location = sample.Location[i:]
190 break
191 }
192 }
193 }
194 }
195
View as plain text