summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAliaksey Kandratsenka <alk@tut.by>2014-10-18 16:35:57 -0700
committerAliaksey Kandratsenka <alk@tut.by>2014-10-18 16:35:57 -0700
commit8c3dc52fcfe02412a529769a22cbc75388a5d368 (patch)
treeb83c4963199bd98891fef1cb01046f236e40b8ab
parent44c61ce6c4c713b194330641f400bbf64fd2abec (diff)
downloadgperftools-8c3dc52fcfe02412a529769a22cbc75388a5d368.tar.gz
issue-654: [pprof] handle split text segments
This applies patch by user simonb. Quoting: Relocation packing splits a single executable load segment into two. Before: LOAD 0x000000 0x00000000 0x00000000 0x2034d28 0x2034d28 R E 0x1000 LOAD 0x2035888 0x02036888 0x02036888 0x182d38 0x1a67d0 RW 0x1000 After: LOAD 0x000000 0x00000000 0x00000000 0x14648 0x14648 R E 0x1000 LOAD 0x014648 0x0020c648 0x0020c648 0x1e286e0 0x1e286e0 R E 0x1000 ... LOAD 0x1e3d888 0x02036888 0x02036888 0x182d38 0x1a67d0 RW 0x1000 The .text section is in the second LOAD, and this is not at offset/address zero. The result is that this library shows up in /proc/self/maps as multiple executable entries, for example (note: this trace is not from the library dissected above, but rather from an earlier version of it): 73b0c000-73b21000 r-xp 00000000 b3:19 786460 /data/.../libchrome.2160.0.so 73b21000-73d12000 ---p 00000000 00:00 0 73d12000-75a90000 r-xp 00014000 b3:19 786460 /data/.../libchrome.2160.0.so 75a90000-75c0d000 rw-p 01d91000 b3:19 786460 /data/.../libchrome.2160.0.so When parsing this, pprof needs to merge the two r-xp entries above into a single entry, otherwise the addresses it prints are incorrect. The following fix against 2.2.1 was sufficient to make pprof --text print the correct output. Untested with other pprof options.
-rwxr-xr-xsrc/pprof10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/pprof b/src/pprof
index 0135fed..719e859 100755
--- a/src/pprof
+++ b/src/pprof
@@ -4395,6 +4395,7 @@ sub ParseLibraries {
my $zero_offset = HexExtend("0");
my $buildvar = "";
+ my $priorlib = "";
foreach my $l (split("\n", $map)) {
if ($l =~ m/^\s*build=(.*)$/) {
$buildvar = $1;
@@ -4451,7 +4452,16 @@ sub ParseLibraries {
}
}
+ # If we find multiple executable segments for a single library, merge them
+ # into a single entry that spans the complete address range.
+ if ($lib eq $priorlib) {
+ my $prior = pop(@{$result});
+ $start = @$prior[1];
+ # TODO $offset may be wrong if .text is not in the final segment.
+ }
+
push(@{$result}, [$lib, $start, $finish, $offset]);
+ $priorlib = $lib;
}
# Append special entry for additional library (not relocated)