Skip to content

Commit 73b8e5f

Browse files
mkevachyangah
authored andcommitted
runtime/pprof: remove "deleted" suffix while parsing maps file
If binary file of a running program was deleted or moved, maps file (/proc/pid/maps) will contain lines that have this binary filename suffixed with "(deleted)" string. This suffix stayed as a part of the filename and made remote profiling slightly more difficult by requiring from a user to rename binary file to include this suffix. This change cleans up the filename and removes this suffix and thus simplify debugging. Fixes #25740 Change-Id: Ib3c8c3b9ef536c2ac037fcc14e8037fa5c960036 Reviewed-on: https://go-review.googlesource.com/116395 Run-TryBot: Hyang-Ah Hana Kim <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]>
1 parent 031a35e commit 73b8e5f

File tree

2 files changed

+88
-15
lines changed

2 files changed

+88
-15
lines changed

src/runtime/pprof/proto.go

+8
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,14 @@ func parseProcSelfMaps(data []byte, addMapping func(lo, hi, offset uint64, file,
524524
continue
525525
}
526526
file := string(line)
527+
528+
// Trim deleted file marker.
529+
deletedStr := " (deleted)"
530+
deletedLen := len(deletedStr)
531+
if len(file) >= deletedLen && file[len(file)-deletedLen:] == deletedStr {
532+
file = file[:len(file)-deletedLen]
533+
}
534+
527535
if len(inode) == 1 && inode[0] == '0' && file == "" {
528536
// Huge-page text mappings list the initial fragment of
529537
// mapped but unpopulated memory as being inode 0.

src/runtime/pprof/proto_test.go

+80-15
Original file line numberDiff line numberDiff line change
@@ -216,24 +216,89 @@ c000000000-c000036000 rw-p 00000000 00:00 0
216216
07000000 07093000 06c00000 /path/to/gobench_server_main
217217
`
218218

219+
var profSelfMapsTestsWithDeleted = `
220+
00400000-0040b000 r-xp 00000000 fc:01 787766 /bin/cat (deleted)
221+
0060a000-0060b000 r--p 0000a000 fc:01 787766 /bin/cat (deleted)
222+
0060b000-0060c000 rw-p 0000b000 fc:01 787766 /bin/cat (deleted)
223+
014ab000-014cc000 rw-p 00000000 00:00 0 [heap]
224+
7f7d76af8000-7f7d7797c000 r--p 00000000 fc:01 1318064 /usr/lib/locale/locale-archive
225+
7f7d7797c000-7f7d77b36000 r-xp 00000000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
226+
7f7d77b36000-7f7d77d36000 ---p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
227+
7f7d77d36000-7f7d77d3a000 r--p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
228+
7f7d77d3a000-7f7d77d3c000 rw-p 001be000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
229+
7f7d77d3c000-7f7d77d41000 rw-p 00000000 00:00 0
230+
7f7d77d41000-7f7d77d64000 r-xp 00000000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
231+
7f7d77f3f000-7f7d77f42000 rw-p 00000000 00:00 0
232+
7f7d77f61000-7f7d77f63000 rw-p 00000000 00:00 0
233+
7f7d77f63000-7f7d77f64000 r--p 00022000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
234+
7f7d77f64000-7f7d77f65000 rw-p 00023000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
235+
7f7d77f65000-7f7d77f66000 rw-p 00000000 00:00 0
236+
7ffc342a2000-7ffc342c3000 rw-p 00000000 00:00 0 [stack]
237+
7ffc34343000-7ffc34345000 r-xp 00000000 00:00 0 [vdso]
238+
ffffffffff600000-ffffffffff601000 r-xp 00000090 00:00 0 [vsyscall]
239+
->
240+
00400000 0040b000 00000000 /bin/cat
241+
7f7d7797c000 7f7d77b36000 00000000 /lib/x86_64-linux-gnu/libc-2.19.so
242+
7f7d77d41000 7f7d77d64000 00000000 /lib/x86_64-linux-gnu/ld-2.19.so
243+
7ffc34343000 7ffc34345000 00000000 [vdso]
244+
ffffffffff600000 ffffffffff601000 00000090 [vsyscall]
245+
246+
00400000-0040b000 r-xp 00000000 fc:01 787766 /bin/cat with space
247+
0060a000-0060b000 r--p 0000a000 fc:01 787766 /bin/cat with space
248+
0060b000-0060c000 rw-p 0000b000 fc:01 787766 /bin/cat with space
249+
014ab000-014cc000 rw-p 00000000 00:00 0 [heap]
250+
7f7d76af8000-7f7d7797c000 r--p 00000000 fc:01 1318064 /usr/lib/locale/locale-archive
251+
7f7d7797c000-7f7d77b36000 r-xp 00000000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
252+
7f7d77b36000-7f7d77d36000 ---p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
253+
7f7d77d36000-7f7d77d3a000 r--p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
254+
7f7d77d3a000-7f7d77d3c000 rw-p 001be000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
255+
7f7d77d3c000-7f7d77d41000 rw-p 00000000 00:00 0
256+
7f7d77d41000-7f7d77d64000 r-xp 00000000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
257+
7f7d77f3f000-7f7d77f42000 rw-p 00000000 00:00 0
258+
7f7d77f61000-7f7d77f63000 rw-p 00000000 00:00 0
259+
7f7d77f63000-7f7d77f64000 r--p 00022000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
260+
7f7d77f64000-7f7d77f65000 rw-p 00023000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
261+
7f7d77f65000-7f7d77f66000 rw-p 00000000 00:00 0
262+
7ffc342a2000-7ffc342c3000 rw-p 00000000 00:00 0 [stack]
263+
7ffc34343000-7ffc34345000 r-xp 00000000 00:00 0 [vdso]
264+
ffffffffff600000-ffffffffff601000 r-xp 00000090 00:00 0 [vsyscall]
265+
->
266+
00400000 0040b000 00000000 /bin/cat with space
267+
7f7d7797c000 7f7d77b36000 00000000 /lib/x86_64-linux-gnu/libc-2.19.so
268+
7f7d77d41000 7f7d77d64000 00000000 /lib/x86_64-linux-gnu/ld-2.19.so
269+
7ffc34343000 7ffc34345000 00000000 [vdso]
270+
ffffffffff600000 ffffffffff601000 00000090 [vsyscall]
271+
`
272+
219273
func TestProcSelfMaps(t *testing.T) {
220-
for tx, tt := range strings.Split(profSelfMapsTests, "\n\n") {
221-
i := strings.Index(tt, "->\n")
222-
if i < 0 {
223-
t.Fatal("malformed test case")
224-
}
225-
in, out := tt[:i], tt[i+len("->\n"):]
226-
if len(out) > 0 && out[len(out)-1] != '\n' {
227-
out += "\n"
228-
}
229-
var buf bytes.Buffer
230-
parseProcSelfMaps([]byte(in), func(lo, hi, offset uint64, file, buildID string) {
231-
fmt.Fprintf(&buf, "%08x %08x %08x %s\n", lo, hi, offset, file)
232-
})
233-
if buf.String() != out {
234-
t.Errorf("#%d: have:\n%s\nwant:\n%s\n%q\n%q", tx, buf.String(), out, buf.String(), out)
274+
275+
f := func(t *testing.T, input string) {
276+
for tx, tt := range strings.Split(input, "\n\n") {
277+
i := strings.Index(tt, "->\n")
278+
if i < 0 {
279+
t.Fatal("malformed test case")
280+
}
281+
in, out := tt[:i], tt[i+len("->\n"):]
282+
if len(out) > 0 && out[len(out)-1] != '\n' {
283+
out += "\n"
284+
}
285+
var buf bytes.Buffer
286+
parseProcSelfMaps([]byte(in), func(lo, hi, offset uint64, file, buildID string) {
287+
fmt.Fprintf(&buf, "%08x %08x %08x %s\n", lo, hi, offset, file)
288+
})
289+
if buf.String() != out {
290+
t.Errorf("#%d: have:\n%s\nwant:\n%s\n%q\n%q", tx, buf.String(), out, buf.String(), out)
291+
}
235292
}
236293
}
294+
295+
t.Run("Normal", func(t *testing.T) {
296+
f(t, profSelfMapsTests)
297+
})
298+
299+
t.Run("WithDeletedFile", func(t *testing.T) {
300+
f(t, profSelfMapsTestsWithDeleted)
301+
})
237302
}
238303

239304
// TestMapping checkes the mapping section of CPU profiles

0 commit comments

Comments
 (0)