diff --git a/profile/merge.go b/profile/merge.go index 8a51690be4..5e6c80bf0a 100644 --- a/profile/merge.go +++ b/profile/merge.go @@ -328,10 +328,10 @@ func (l *Location) key() locationKey { lines := make([]string, len(l.Line)*3) for i, line := range l.Line { if line.Function != nil { - lines[i*2] = strconv.FormatUint(line.Function.ID, 16) + lines[i*3] = strconv.FormatUint(line.Function.ID, 16) } - lines[i*2+1] = strconv.FormatInt(line.Line, 16) - lines[i*2+2] = strconv.FormatInt(line.Column, 16) + lines[i*3+1] = strconv.FormatInt(line.Line, 16) + lines[i*3+2] = strconv.FormatInt(line.Column, 16) } key.lines = strings.Join(lines, "|") return key diff --git a/profile/merge_test.go b/profile/merge_test.go index d2d05e63e7..83f32e789e 100644 --- a/profile/merge_test.go +++ b/profile/merge_test.go @@ -201,6 +201,38 @@ func TestLocationIDMap(t *testing.T) { } } +func TestMergePreservesInlineFrameColumns(t *testing.T) { + profileWithColumn := func(column int64) *Profile { + functions := []*Function{ + {ID: 1, Name: "foo", Filename: "x.go"}, + {ID: 2, Name: "bar", Filename: "x.go"}, + } + location := &Location{ + ID: 1, + Address: 0x1000, + Line: []Line{ + {Function: functions[0], Line: 10, Column: column}, + {Function: functions[1], Line: 20, Column: 7}, + }, + } + return &Profile{ + PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"}, + SampleType: []*ValueType{{Type: "samples", Unit: "count"}}, + Sample: []*Sample{{Location: []*Location{location}, Value: []int64{1}}}, + Location: []*Location{location}, + Function: functions, + } + } + + merged, err := Merge([]*Profile{profileWithColumn(3), profileWithColumn(9)}) + if err != nil { + t.Fatalf("Merge() failed: %v", err) + } + if got, want := len(merged.Location), 2; got != want { + t.Fatalf("Merge() produced %d locations, want %d", got, want) + } +} + func BenchmarkMerge(b *testing.B) { data := proftest.LargeProfile(b) for n := 1; n <= 2; n++ { // Merge either 1 or 2 instances.