浏览代码

Combine adjacent mappings even if offsets are unavailable

Some profile handlers will split mappings into multiple adjacent
entries. This interferes with pprof when overriding the main binary.

Currently there is code that attempts to combine these mappings, but
it fails if the mapping offsets aren't available. Add a check to
combine them in that situation.
Raul Silvera 8 年前
父节点
当前提交
5509abdceb
共有 1 个文件被更改,包括 31 次插入5 次删除
  1. 31
    5
      profile/profile.go

+ 31
- 5
profile/profile.go 查看文件

216
 		mappings := []*Mapping{p.Mapping[0]}
216
 		mappings := []*Mapping{p.Mapping[0]}
217
 		for _, m := range p.Mapping[1:] {
217
 		for _, m := range p.Mapping[1:] {
218
 			lm := mappings[len(mappings)-1]
218
 			lm := mappings[len(mappings)-1]
219
-			if offset := lm.Offset + (lm.Limit - lm.Start); lm.Limit == m.Start &&
220
-				offset == m.Offset &&
221
-				(lm.File == m.File || lm.File == "") {
222
-				lm.File = m.File
219
+			if adjacent(lm, m) {
223
 				lm.Limit = m.Limit
220
 				lm.Limit = m.Limit
224
-				if lm.BuildID == "" {
221
+				if m.File != "" {
222
+					lm.File = m.File
223
+				}
224
+				if m.BuildID != "" {
225
 					lm.BuildID = m.BuildID
225
 					lm.BuildID = m.BuildID
226
 				}
226
 				}
227
 				p.updateLocationMapping(m, lm)
227
 				p.updateLocationMapping(m, lm)
255
 	}
255
 	}
256
 }
256
 }
257
 
257
 
258
+// adjacent returns whether two mapping entries represent the same
259
+// mapping that has been split into two. Check that their addresses are adjacent,
260
+// and if the offsets match, if they are available.
261
+func adjacent(m1, m2 *Mapping) bool {
262
+	if m1.File != "" && m2.File != "" {
263
+		if m1.File != m2.File {
264
+			return false
265
+		}
266
+	}
267
+	if m1.BuildID != "" && m2.BuildID != "" {
268
+		if m1.BuildID != m2.BuildID {
269
+			return false
270
+		}
271
+	}
272
+	if m1.Limit != m2.Start {
273
+		return false
274
+	}
275
+	if m1.Offset != 0 && m2.Offset != 0 {
276
+		offset := m1.Offset + (m1.Limit - m1.Start)
277
+		if offset != m2.Offset {
278
+			return false
279
+		}
280
+	}
281
+	return true
282
+}
283
+
258
 func (p *Profile) updateLocationMapping(from, to *Mapping) {
284
 func (p *Profile) updateLocationMapping(from, to *Mapping) {
259
 	for _, l := range p.Location {
285
 	for _, l := range p.Location {
260
 		if l.Mapping == from {
286
 		if l.Mapping == from {