Commit b079869d authored by Hana Kim's avatar Hana Kim Committed by Peter Weinberger

internal/pprof/profile: parse mutex profile including comments

Skip lines if they are empty or starting with "#" which are valid
legacy pprof output format.

Fixes #18025

Change-Id: I7aee439171496932637b8ae3188700911f569b16
Reviewed-on: https://go-review.googlesource.com/33454Reviewed-by: 's avatarPeter Weinberger <pjw@google.com>
parent 7a92d0b1
...@@ -686,10 +686,19 @@ func scaleHeapSample(count, size, rate int64) (int64, int64) { ...@@ -686,10 +686,19 @@ func scaleHeapSample(count, size, rate int64) (int64, int64) {
// the runtime might write a serialized Profile directly making this unnecessary.) // the runtime might write a serialized Profile directly making this unnecessary.)
func parseContention(b []byte) (*Profile, error) { func parseContention(b []byte) (*Profile, error) {
r := bytes.NewBuffer(b) r := bytes.NewBuffer(b)
l, err := r.ReadString('\n') var l string
var err error
for {
// Skip past comments and empty lines seeking a real header.
l, err = r.ReadString('\n')
if err != nil { if err != nil {
return nil, errUnrecognized return nil, err
} }
if !isSpaceOrComment(l) {
break
}
}
if strings.HasPrefix(l, "--- contentionz ") { if strings.HasPrefix(l, "--- contentionz ") {
return parseCppContention(r) return parseCppContention(r)
} else if strings.HasPrefix(l, "--- mutex:") { } else if strings.HasPrefix(l, "--- mutex:") {
...@@ -729,6 +738,9 @@ func parseCppContention(r *bytes.Buffer) (*Profile, error) { ...@@ -729,6 +738,9 @@ func parseCppContention(r *bytes.Buffer) (*Profile, error) {
break break
} }
} }
if isSpaceOrComment(l) {
continue
}
if l = strings.TrimSpace(l); l == "" { if l = strings.TrimSpace(l); l == "" {
continue continue
...@@ -773,6 +785,7 @@ func parseCppContention(r *bytes.Buffer) (*Profile, error) { ...@@ -773,6 +785,7 @@ func parseCppContention(r *bytes.Buffer) (*Profile, error) {
locs := make(map[uint64]*Location) locs := make(map[uint64]*Location)
for { for {
if !isSpaceOrComment(l) {
if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") { if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") {
break break
} }
...@@ -799,6 +812,7 @@ func parseCppContention(r *bytes.Buffer) (*Profile, error) { ...@@ -799,6 +812,7 @@ func parseCppContention(r *bytes.Buffer) (*Profile, error) {
Value: value, Value: value,
Location: sloc, Location: sloc,
}) })
}
if l, err = r.ReadString('\n'); err != nil { if l, err = r.ReadString('\n'); err != nil {
if err != io.EOF { if err != io.EOF {
......
...@@ -22,3 +22,58 @@ func TestEmptyProfile(t *testing.T) { ...@@ -22,3 +22,58 @@ func TestEmptyProfile(t *testing.T) {
t.Errorf("Profile should be empty, got %#v", p) t.Errorf("Profile should be empty, got %#v", p)
} }
} }
func TestParseContention(t *testing.T) {
tests := []struct {
name string
in string
wantErr bool
}{
{
name: "valid",
in: `--- mutex:
cycles/second=3491920901
sampling period=1
43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31
34035731690 15760 @ 0x45e851 0x45f764 0x4a2b17 0x44ea31
`,
},
{
name: "valid with comment",
in: `--- mutex:
cycles/second=3491920901
sampling period=1
43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31
# 0x45e850 sync.(*Mutex).Unlock+0x80 /go/src/sync/mutex.go:126
# 0x45f763 sync.(*RWMutex).Unlock+0x83 /go/src/sync/rwmutex.go:125
# 0x4a2be0 main.main.func3+0x70 /go/src/internal/pprof/profile/a_binary.go:58
34035731690 15760 @ 0x45e851 0x45f764 0x4a2b17 0x44ea31
# 0x45e850 sync.(*Mutex).Unlock+0x80 /go/src/sync/mutex.go:126
# 0x45f763 sync.(*RWMutex).Unlock+0x83 /go/src/sync/rwmutex.go:125
# 0x4a2b16 main.main.func2+0xd6 /go/src/internal/pprof/profile/a_binary.go:48
`,
},
{
name: "empty",
in: `--- mutex:`,
wantErr: true,
},
{
name: "invalid header",
in: `--- channel:
43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31`,
wantErr: true,
},
}
for _, tc := range tests {
_, err := parseContention([]byte(tc.in))
if tc.wantErr && err == nil {
t.Errorf("parseContention(%q) succeeded unexpectedly", tc.name)
}
if !tc.wantErr && err != nil {
t.Errorf("parseContention(%q) failed unexpectedly: %v", tc.name, err)
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment