Преглед изворни кода

Detect concatenated profile and give clearer error message (#304)

This change detects concatenated profiles by checking if time_nanos appears more than once in the profile being parsed.

Fixes #273
Margaret Nolan пре 7 година
родитељ
комит
8cd90f1e63
3 измењених фајлова са 24 додато и 2 уклоњено
  1. 6
    1
      profile/encode.go
  2. 2
    1
      profile/profile.go
  3. 16
    0
      profile/profile_test.go

+ 6
- 1
profile/encode.go Прегледај датотеку

@@ -214,7 +214,12 @@ var profileDecoder = []decoder{
214 214
 	// int64 keep_frames = 8
215 215
 	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },
216 216
 	// int64 time_nanos = 9
217
-	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).TimeNanos) },
217
+	func(b *buffer, m message) error {
218
+		if m.(*Profile).TimeNanos != 0 {
219
+			return errConcatProfile
220
+		}
221
+		return decodeInt64(b, &m.(*Profile).TimeNanos)
222
+	},
218 223
 	// int64 duration_nanos = 10
219 224
 	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },
220 225
 	// ValueType period_type = 11

+ 2
- 1
profile/profile.go Прегледај датотеку

@@ -164,7 +164,7 @@ func ParseData(data []byte) (*Profile, error) {
164 164
 			return nil, fmt.Errorf("decompressing profile: %v", err)
165 165
 		}
166 166
 	}
167
-	if p, err = ParseUncompressed(data); err != nil && err != errNoData {
167
+	if p, err = ParseUncompressed(data); err != nil && err != errNoData && err != errConcatProfile {
168 168
 		p, err = parseLegacy(data)
169 169
 	}
170 170
 
@@ -181,6 +181,7 @@ func ParseData(data []byte) (*Profile, error) {
181 181
 var errUnrecognized = fmt.Errorf("unrecognized profile format")
182 182
 var errMalformed = fmt.Errorf("malformed profile format")
183 183
 var errNoData = fmt.Errorf("empty input file")
184
+var errConcatProfile = fmt.Errorf("concatenated profiles detected")
184 185
 
185 186
 func parseLegacy(data []byte) (*Profile, error) {
186 187
 	parsers := []func([]byte) (*Profile, error){

+ 16
- 0
profile/profile_test.go Прегледај датотеку

@@ -108,6 +108,21 @@ func TestParseError(t *testing.T) {
108 108
 	}
109 109
 }
110 110
 
111
+func TestParseConcatentated(t *testing.T) {
112
+	prof := testProfile1.Copy()
113
+	// Write the profile twice to buffer to create concatented profile.
114
+	buf := bytes.NewBuffer(nil)
115
+	prof.Write(buf)
116
+	prof.Write(buf)
117
+	_, err := Parse(buf)
118
+	if err == nil {
119
+		t.Fatalf("got nil, want error")
120
+	}
121
+	if got, want := err.Error(), "parsing profile: concatenated profiles detected"; want != got {
122
+		t.Fatalf("got error %q, want error %q", got, want)
123
+	}
124
+}
125
+
111 126
 func TestCheckValid(t *testing.T) {
112 127
 	const path = "testdata/java.cpu"
113 128
 
@@ -276,6 +291,7 @@ var cpuL = []*Location{
276 291
 }
277 292
 
278 293
 var testProfile1 = &Profile{
294
+	TimeNanos:     10000,
279 295
 	PeriodType:    &ValueType{Type: "cpu", Unit: "milliseconds"},
280 296
 	Period:        1,
281 297
 	DurationNanos: 10e9,