Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pprof incorrectly reports addresses where .text is not in the first loadable segment #654

Open
GoogleCodeExporter opened this issue Jul 23, 2015 · 3 comments

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?
1. Build chromium for Android with packed relocations.
2. Capture a .prof file.
3. Process with pprof.

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.

$ diff -c ./gperftools-2.2.1/src/pprof ./pprof
*** ./gperftools-2.2.1/src/pprof    2014-04-13 02:35:40.000000000 +0100
--- ./pprof 2014-10-13 16:48:37.039256051 +0100
***************
*** 4352,4357 ****
--- 4352,4358 ----
    my $zero_offset = HexExtend("0");

    my $buildvar = "";
+   my $priorlib = "";
    foreach my $l (split("\n", $map)) {
      if ($l =~ m/^\s*build=(.*)$/) {
        $buildvar = $1;
***************
*** 4408,4414 ****
--- 4409,4424 ----
        }
      }

+     # 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)

Original issue reported on code.google.com by sim...@google.com on 15 Oct 2014 at 1:30

@GoogleCodeExporter
Copy link
Author

Thanks. Applied.

Original comment by alkondratenko on 18 Oct 2014 at 11:46

  • Changed state: Fixed

@GoogleCodeExporter
Copy link
Author

This seems to have broken symbol gathering on my system. If I revert 8c3dc52, 
symbols show up again in pprof. Attached an example profile (with binary names 
anonymized)

Original comment by tlip...@gmail.com on 14 Jun 2015 at 4:05

Attachments:

@GoogleCodeExporter
Copy link
Author

Thanks. Reopening.

I'm willing to revert. Will do that next week.

BTW, I was sure that contention profiling is was never open-sourced, so I'm 
curious how you managed to generate contention profile?

Original comment by alkondratenko on 14 Jun 2015 at 4:51

  • Changed state: Accepted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant