aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vendor/github.com/google/pprof/profile
diff options
context:
space:
mode:
authorAlberto Donizetti <alb.donizetti@gmail.com>2017-06-20 17:40:21 +0200
committerBrad Fitzpatrick <bradfitz@golang.org>2017-06-20 18:31:06 +0000
commit3d13b5e00c9bc065d83e27d787a64adc683cea02 (patch)
tree60f71d89af63a6ee45cc73e79336c271511c5883 /src/cmd/vendor/github.com/google/pprof/profile
parentdc8b4e65a7a68e102484020efbf80cecd2d515bd (diff)
downloadgo-3d13b5e00c9bc065d83e27d787a64adc683cea02.tar.xz
cmd/vendor/github.com/google/pprof: refresh from upstream
Updating to commit fffc5831a499a958516664a34cb7ba2b9e228793 from github.com/google/pprof Fixes #19380 Change-Id: I7a0c64101f42b494c4a469c41628374272eccf95 Reviewed-on: https://go-review.googlesource.com/46155 Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd/vendor/github.com/google/pprof/profile')
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go2
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/profile.go5
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/profile_test.go28
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/proto.go14
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/proto_test.go12
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/prune.go47
-rw-r--r--src/cmd/vendor/github.com/google/pprof/profile/prune_test.go91
7 files changed, 153 insertions, 46 deletions
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go b/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go
index 7b40f5d24c..544edf0f75 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/legacy_java_profile.go
@@ -212,7 +212,7 @@ func parseJavaSamples(pType string, b []byte, p *Profile) ([]byte, map[uint64]*L
switch pType {
case "heap":
const javaHeapzSamplingRate = 524288 // 512K
- s.NumLabel = map[string][]int64{"bytes": []int64{s.Value[1] / s.Value[0]}}
+ s.NumLabel = map[string][]int64{"bytes": {s.Value[1] / s.Value[0]}}
s.Value[0], s.Value[1] = scaleHeapSample(s.Value[0], s.Value[1], javaHeapzSamplingRate)
case "contention":
if period := p.Period; period != 0 {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/profile.go b/src/cmd/vendor/github.com/google/pprof/profile/profile.go
index fb3d4fd4fb..13888f1594 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/profile.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/profile.go
@@ -596,10 +596,11 @@ func (p *Profile) HasFileLines() bool {
}
// Unsymbolizable returns true if a mapping points to a binary for which
-// locations can't be symbolized in principle, at least now.
+// locations can't be symbolized in principle, at least now. Examples are
+// "[vdso]", [vsyscall]" and some others, see the code.
func (m *Mapping) Unsymbolizable() bool {
name := filepath.Base(m.File)
- return name == "[vdso]" || strings.HasPrefix(name, "linux-vdso") || name == "[heap]" || strings.HasPrefix(m.File, "/dev/dri/")
+ return strings.HasPrefix(name, "[") || strings.HasPrefix(name, "linux-vdso") || strings.HasPrefix(m.File, "/dev/dri/")
}
// Copy makes a fully independent copy of a profile.
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go b/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go
index c2319a6500..bae2e8f677 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/profile_test.go
@@ -230,40 +230,40 @@ var testProfile = &Profile{
Location: []*Location{cpuL[0]},
Value: []int64{1000, 1000},
Label: map[string][]string{
- "key1": []string{"tag1"},
- "key2": []string{"tag1"},
+ "key1": {"tag1"},
+ "key2": {"tag1"},
},
},
{
Location: []*Location{cpuL[1], cpuL[0]},
Value: []int64{100, 100},
Label: map[string][]string{
- "key1": []string{"tag2"},
- "key3": []string{"tag2"},
+ "key1": {"tag2"},
+ "key3": {"tag2"},
},
},
{
Location: []*Location{cpuL[2], cpuL[0]},
Value: []int64{10, 10},
Label: map[string][]string{
- "key1": []string{"tag3"},
- "key2": []string{"tag2"},
+ "key1": {"tag3"},
+ "key2": {"tag2"},
},
},
{
Location: []*Location{cpuL[3], cpuL[0]},
Value: []int64{10000, 10000},
Label: map[string][]string{
- "key1": []string{"tag4"},
- "key2": []string{"tag1"},
+ "key1": {"tag4"},
+ "key2": {"tag1"},
},
},
{
Location: []*Location{cpuL[4], cpuL[0]},
Value: []int64{1, 1},
Label: map[string][]string{
- "key1": []string{"tag4"},
- "key2": []string{"tag1"},
+ "key1": {"tag4"},
+ "key2": {"tag1"},
},
},
},
@@ -273,10 +273,10 @@ var testProfile = &Profile{
}
var aggTests = map[string]aggTest{
- "precise": aggTest{true, true, true, true, 5},
- "fileline": aggTest{false, true, true, true, 4},
- "inline_function": aggTest{false, true, false, true, 3},
- "function": aggTest{false, true, false, false, 2},
+ "precise": {true, true, true, true, 5},
+ "fileline": {false, true, true, true, 4},
+ "inline_function": {false, true, false, true, 3},
+ "function": {false, true, false, false, 2},
}
type aggTest struct {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/proto.go b/src/cmd/vendor/github.com/google/pprof/profile/proto.go
index 01b7f7ae18..e7df33ac2b 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/proto.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/proto.go
@@ -71,7 +71,7 @@ func encodeLength(b *buffer, tag int, len int) {
func encodeUint64(b *buffer, tag int, x uint64) {
// append varint to b.data
- encodeVarint(b, uint64(tag)<<3|0)
+ encodeVarint(b, uint64(tag)<<3)
encodeVarint(b, x)
}
@@ -145,13 +145,6 @@ func encodeStrings(b *buffer, tag int, x []string) {
}
}
-func encodeStringOpt(b *buffer, tag int, x string) {
- if x == "" {
- return
- }
- encodeString(b, tag, x)
-}
-
func encodeBool(b *buffer, tag int, x bool) {
if x {
encodeUint64(b, tag, 1)
@@ -161,10 +154,9 @@ func encodeBool(b *buffer, tag int, x bool) {
}
func encodeBoolOpt(b *buffer, tag int, x bool) {
- if x == false {
- return
+ if x {
+ encodeBool(b, tag, x)
}
- encodeBool(b, tag, x)
}
func encodeMessage(b *buffer, tag int, m message) {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go b/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go
index d2a351373e..9578c5b2fe 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/proto_test.go
@@ -100,8 +100,8 @@ var all = &Profile{
{
Location: []*Location{testL[0], testL[1], testL[2], testL[1], testL[1]},
Label: map[string][]string{
- "key1": []string{"value1"},
- "key2": []string{"value2"},
+ "key1": {"value1"},
+ "key2": {"value2"},
},
Value: []int64{10, 20},
},
@@ -109,12 +109,12 @@ var all = &Profile{
Location: []*Location{testL[1], testL[2], testL[0], testL[1]},
Value: []int64{30, 40},
Label: map[string][]string{
- "key1": []string{"value1"},
- "key2": []string{"value2"},
+ "key1": {"value1"},
+ "key2": {"value2"},
},
NumLabel: map[string][]int64{
- "key1": []int64{1, 2},
- "key2": []int64{3, 4},
+ "key1": {1, 2},
+ "key2": {3, 4},
},
},
},
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/prune.go b/src/cmd/vendor/github.com/google/pprof/profile/prune.go
index cf9cbb3894..02d21a8184 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/prune.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/prune.go
@@ -22,6 +22,39 @@ import (
"strings"
)
+var (
+ reservedNames = []string{"(anonymous namespace)", "operator()"}
+ bracketRx = func() *regexp.Regexp {
+ var quotedNames []string
+ for _, name := range append(reservedNames, "(") {
+ quotedNames = append(quotedNames, regexp.QuoteMeta(name))
+ }
+ return regexp.MustCompile(strings.Join(quotedNames, "|"))
+ }()
+)
+
+// simplifyFunc does some primitive simplification of function names.
+func simplifyFunc(f string) string {
+ // Account for leading '.' on the PPC ELF v1 ABI.
+ funcName := strings.TrimPrefix(f, ".")
+ // Account for unsimplified names -- try to remove the argument list by trimming
+ // starting from the first '(', but skipping reserved names that have '('.
+ for _, ind := range bracketRx.FindAllStringSubmatchIndex(funcName, -1) {
+ foundReserved := false
+ for _, res := range reservedNames {
+ if funcName[ind[0]:ind[1]] == res {
+ foundReserved = true
+ break
+ }
+ }
+ if !foundReserved {
+ funcName = funcName[:ind[0]]
+ break
+ }
+ }
+ return funcName
+}
+
// Prune removes all nodes beneath a node matching dropRx, and not
// matching keepRx. If the root node of a Sample matches, the sample
// will have an empty stack.
@@ -33,12 +66,7 @@ func (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) {
var i int
for i = len(loc.Line) - 1; i >= 0; i-- {
if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
- // Account for leading '.' on the PPC ELF v1 ABI.
- funcName := strings.TrimPrefix(fn.Name, ".")
- // Account for unsimplified names -- trim starting from the first '('.
- if index := strings.Index(funcName, "("); index > 0 {
- funcName = funcName[:index]
- }
+ funcName := simplifyFunc(fn.Name)
if dropRx.MatchString(funcName) {
if keepRx == nil || !keepRx.MatchString(funcName) {
break
@@ -126,12 +154,7 @@ func (p *Profile) PruneFrom(dropRx *regexp.Regexp) {
for _, loc := range p.Location {
for i := 0; i < len(loc.Line); i++ {
if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
- // Account for leading '.' on the PPC ELF v1 ABI.
- funcName := strings.TrimPrefix(fn.Name, ".")
- // Account for unsimplified names -- trim starting from the first '('.
- if index := strings.Index(funcName, "("); index > 0 {
- funcName = funcName[:index]
- }
+ funcName := simplifyFunc(fn.Name)
if dropRx.MatchString(funcName) {
// Found matching entry to prune.
pruneBeneath[loc.ID] = true
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go b/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go
index 58fa25ee2d..75d7c6d4f7 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/prune_test.go
@@ -25,6 +25,7 @@ func TestPrune(t *testing.T) {
want string
}{
{in1, out1},
+ {in2, out2},
} {
in := test.in.Copy()
in.RemoveUninteresting()
@@ -50,6 +51,10 @@ var funs = []*Function{
{ID: 4, Name: "fun3", SystemName: "fun3", Filename: "fun.c"},
{ID: 5, Name: "fun4", SystemName: "fun4", Filename: "fun.c"},
{ID: 6, Name: "fun5", SystemName: "fun5", Filename: "fun.c"},
+ {ID: 7, Name: "unsimplified_fun(int)", SystemName: "unsimplified_fun(int)", Filename: "fun.c"},
+ {ID: 8, Name: "Foo::(anonymous namespace)::Test::Bar", SystemName: "Foo::(anonymous namespace)::Test::Bar", Filename: "fun.c"},
+ {ID: 9, Name: "Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar)", SystemName: "Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar)", Filename: "fun.c"},
+ {ID: 10, Name: "Foo::operator()(::Bar)", SystemName: "Foo::operator()(::Bar)", Filename: "fun.c"},
}
var locs1 = []*Location{
@@ -137,3 +142,89 @@ Locations
4: 0x0 fun5 fun.c:2 s=0
Mappings
`
+
+var locs2 = []*Location{
+ {
+ ID: 1,
+ Line: []Line{
+ {Function: funs[0], Line: 1},
+ },
+ },
+ {
+ ID: 2,
+ Line: []Line{
+ {Function: funs[6], Line: 1},
+ },
+ },
+ {
+ ID: 3,
+ Line: []Line{
+ {Function: funs[7], Line: 1},
+ },
+ },
+ {
+ ID: 4,
+ Line: []Line{
+ {Function: funs[8], Line: 1},
+ },
+ },
+ {
+ ID: 5,
+ Line: []Line{
+ {Function: funs[9], Line: 1},
+ },
+ },
+}
+
+var in2 = &Profile{
+ PeriodType: &ValueType{Type: "cpu", Unit: "milliseconds"},
+ Period: 1,
+ DurationNanos: 10e9,
+ SampleType: []*ValueType{
+ {Type: "samples", Unit: "count"},
+ {Type: "cpu", Unit: "milliseconds"},
+ },
+ Sample: []*Sample{
+ // Unsimplified name with parameters shouldn't match.
+ {
+ Location: []*Location{locs2[1], locs2[0]},
+ Value: []int64{1, 1},
+ },
+ // .*Foo::.*::Bar.* should (and will be dropped) regardless of the anonymous namespace.
+ {
+ Location: []*Location{locs2[2], locs2[0]},
+ Value: []int64{1, 1},
+ },
+ // .*Foo::.*::Bar.* shouldn't match inside the parameter list.
+ {
+ Location: []*Location{locs2[3], locs2[0]},
+ Value: []int64{1, 1},
+ },
+ // .*operator\(\) should match, regardless of parameters.
+ {
+ Location: []*Location{locs2[4], locs2[0]},
+ Value: []int64{1, 1},
+ },
+ },
+ Location: locs2,
+ Function: funs,
+ DropFrames: `unsimplified_fun\(int\)|.*Foo::.*::Bar.*|.*operator\(\)`,
+}
+
+const out2 = `PeriodType: cpu milliseconds
+Period: 1
+Duration: 10s
+Samples:
+samples/count cpu/milliseconds
+ 1 1: 2 1
+ 1 1: 1
+ 1 1: 4 1
+ 1 1: 1
+Locations
+ 1: 0x0 main main.c:1 s=0
+ 2: 0x0 unsimplified_fun(int) fun.c:1 s=0
+ 3: 0x0 Foo::(anonymous namespace)::Test::Bar fun.c:1 s=0
+ 4: 0x0 Hello::(anonymous namespace)::World(const Foo::(anonymous namespace)::Test::Bar) fun.c:1 s=0
+ 5: 0x0 Foo::operator()(::Bar) fun.c:1 s=0
+Mappings
+`