| Index: third_party/tcmalloc/chromium/src/pprof
|
| diff --git a/third_party/tcmalloc/chromium/src/pprof b/third_party/tcmalloc/chromium/src/pprof
|
| index 03bafa4446a1e520542cb953b04b314a4c1b1fe4..2d889d0e08efcc5e944624157c5e3812ff14b441 100755
|
| --- a/third_party/tcmalloc/chromium/src/pprof
|
| +++ b/third_party/tcmalloc/chromium/src/pprof
|
| @@ -72,7 +72,7 @@ use strict;
|
| use warnings;
|
| use Getopt::Long;
|
|
|
| -my $PPROF_VERSION = "1.7";
|
| +my $PPROF_VERSION = "1.8.2";
|
|
|
| # These are the object tools we use which can come from a
|
| # user-specified location using --tools, from the PPROF_TOOLS
|
| @@ -156,7 +156,8 @@ pprof [options] <profile>
|
| The /<service> can be $HEAP_PAGE, $PROFILE_PAGE, /pprof/pmuprofile,
|
| $GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,
|
| $CENSUSPROFILE_PAGE, or /pprof/filteredprofile.
|
| - For instance: "pprof http://myserver.com:80$HEAP_PAGE".
|
| + For instance:
|
| + pprof http://myserver.com:80$HEAP_PAGE
|
| If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).
|
| pprof --symbols <program>
|
| Maps addresses to symbol names. In this mode, stdin should be a
|
| @@ -545,7 +546,7 @@ sub Init() {
|
| ConfigureObjTools($main::prog)
|
| }
|
|
|
| - # Break the opt_list_prefix into the prefix_list array
|
| + # Break the opt_lib_prefix into the prefix_list array
|
| @prefix_list = split (',', $main::opt_lib_prefix);
|
|
|
| # Remove trailing / from the prefixes, in the list to prevent
|
| @@ -643,7 +644,7 @@ sub Main() {
|
| if ($main::opt_disasm) {
|
| PrintDisassembly($libs, $flat, $cumulative, $main::opt_disasm);
|
| } elsif ($main::opt_list) {
|
| - PrintListing($libs, $flat, $cumulative, $main::opt_list);
|
| + PrintListing($total, $libs, $flat, $cumulative, $main::opt_list, 0);
|
| } elsif ($main::opt_text) {
|
| # Make sure the output is empty when have nothing to report
|
| # (only matters when --heapcheck is given but we must be
|
| @@ -839,7 +840,7 @@ sub InteractiveCommand {
|
| my $ignore;
|
| ($routine, $ignore) = ParseInteractiveArgs($3);
|
|
|
| - my $profile = ProcessProfile($orig_profile, $symbols, "", $ignore);
|
| + my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
|
| my $reduced = ReduceProfile($symbols, $profile);
|
|
|
| # Get derived profiles
|
| @@ -866,21 +867,22 @@ sub InteractiveCommand {
|
|
|
| return 1;
|
| }
|
| - if (m/^\s*list\s*(.+)/) {
|
| + if (m/^\s*(web)?list\s*(.+)/) {
|
| + my $html = (defined($1) && ($1 eq "web"));
|
| $main::opt_list = 1;
|
|
|
| my $routine;
|
| my $ignore;
|
| - ($routine, $ignore) = ParseInteractiveArgs($1);
|
| + ($routine, $ignore) = ParseInteractiveArgs($2);
|
|
|
| - my $profile = ProcessProfile($orig_profile, $symbols, "", $ignore);
|
| + my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
|
| my $reduced = ReduceProfile($symbols, $profile);
|
|
|
| # Get derived profiles
|
| my $flat = FlatProfile($reduced);
|
| my $cumulative = CumulativeProfile($reduced);
|
|
|
| - PrintListing($libs, $flat, $cumulative, $routine);
|
| + PrintListing($total, $libs, $flat, $cumulative, $routine, $html);
|
| return 1;
|
| }
|
| if (m/^\s*disasm\s*(.+)/) {
|
| @@ -891,7 +893,7 @@ sub InteractiveCommand {
|
| ($routine, $ignore) = ParseInteractiveArgs($1);
|
|
|
| # Process current profile to account for various settings
|
| - my $profile = ProcessProfile($orig_profile, $symbols, "", $ignore);
|
| + my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
|
| my $reduced = ReduceProfile($symbols, $profile);
|
|
|
| # Get derived profiles
|
| @@ -918,7 +920,8 @@ sub InteractiveCommand {
|
| ($focus, $ignore) = ParseInteractiveArgs($2);
|
|
|
| # Process current profile to account for various settings
|
| - my $profile = ProcessProfile($orig_profile, $symbols, $focus, $ignore);
|
| + my $profile = ProcessProfile($total, $orig_profile, $symbols,
|
| + $focus, $ignore);
|
| my $reduced = ReduceProfile($symbols, $profile);
|
|
|
| # Get derived profiles
|
| @@ -946,6 +949,7 @@ sub InteractiveCommand {
|
|
|
|
|
| sub ProcessProfile {
|
| + my $total_count = shift;
|
| my $orig_profile = shift;
|
| my $symbols = shift;
|
| my $focus = shift;
|
| @@ -953,7 +957,6 @@ sub ProcessProfile {
|
|
|
| # Process current profile to account for various settings
|
| my $profile = $orig_profile;
|
| - my $total_count = TotalProfile($profile);
|
| printf("Total: %s %s\n", Unparse($total_count), Units());
|
| if ($focus ne '') {
|
| $profile = FocusProfile($symbols, $profile, $focus);
|
| @@ -1000,6 +1003,11 @@ Commands:
|
| list [routine_regexp] [-ignore1] [-ignore2]
|
| Show source listing of routines whose names match "routine_regexp"
|
|
|
| + weblist [routine_regexp] [-ignore1] [-ignore2]
|
| + Displays a source listing of routines whose names match "routine_regexp"
|
| + in a web browser. You can click on source lines to view the
|
| + corresponding disassembly.
|
| +
|
| top [--cum] [-ignore1] [-ignore2]
|
| top20 [--cum] [-ignore1] [-ignore2]
|
| top37 [--cum] [-ignore1] [-ignore2]
|
| @@ -1175,7 +1183,7 @@ sub PrintText {
|
| $sym);
|
| }
|
| $lines++;
|
| - last if ($line_limit >= 0 && $lines > $line_limit);
|
| + last if ($line_limit >= 0 && $lines >= $line_limit);
|
| }
|
| }
|
|
|
| @@ -1322,13 +1330,33 @@ sub ByName {
|
| return ShortFunctionName($a) cmp ShortFunctionName($b);
|
| }
|
|
|
| -# Print source-listing for all all routines that match $main::opt_list
|
| +# Print source-listing for all all routines that match $list_opts
|
| sub PrintListing {
|
| + my $total = shift;
|
| my $libs = shift;
|
| my $flat = shift;
|
| my $cumulative = shift;
|
| my $list_opts = shift;
|
| + my $html = shift;
|
|
|
| + my $output = \*STDOUT;
|
| + my $fname = "";
|
| +
|
| + if ($html) {
|
| + # Arrange to write the output to a temporary file
|
| + $fname = TempName($main::next_tmpfile, "html");
|
| + $main::next_tmpfile++;
|
| + if (!open(TEMP, ">$fname")) {
|
| + print STDERR "$fname: $!\n";
|
| + return;
|
| + }
|
| + $output = \*TEMP;
|
| + print $output HtmlListingHeader();
|
| + printf $output ("<div class=\"legend\">%s<br>Total: %s %s</div>\n",
|
| + $main::prog, Unparse($total), Units());
|
| + }
|
| +
|
| + my $listed = 0;
|
| foreach my $lib (@{$libs}) {
|
| my $symbol_table = GetProcedureBoundaries($lib->[0], $list_opts);
|
| my $offset = AddressSub($lib->[1], $lib->[3]);
|
| @@ -1340,15 +1368,113 @@ sub PrintListing {
|
| my $addr = AddressAdd($start_addr, $offset);
|
| for (my $i = 0; $i < $length; $i++) {
|
| if (defined($cumulative->{$addr})) {
|
| - PrintSource($lib->[0], $offset,
|
| - $routine, $flat, $cumulative,
|
| - $start_addr, $end_addr);
|
| + $listed += PrintSource(
|
| + $lib->[0], $offset,
|
| + $routine, $flat, $cumulative,
|
| + $start_addr, $end_addr,
|
| + $html,
|
| + $output);
|
| last;
|
| }
|
| $addr = AddressInc($addr);
|
| }
|
| }
|
| }
|
| +
|
| + if ($html) {
|
| + if ($listed > 0) {
|
| + print $output HtmlListingFooter();
|
| + close($output);
|
| + RunWeb($fname);
|
| + } else {
|
| + close($output);
|
| + unlink($fname);
|
| + }
|
| + }
|
| +}
|
| +
|
| +sub HtmlListingHeader {
|
| + return <<'EOF';
|
| +<DOCTYPE html>
|
| +<html>
|
| +<head>
|
| +<title>Pprof listing</title>
|
| +<style type="text/css">
|
| +body {
|
| + font-family: sans-serif;
|
| +}
|
| +h1 {
|
| + font-size: 1.5em;
|
| + margin-bottom: 4px;
|
| +}
|
| +.legend {
|
| + font-size: 1.25em;
|
| +}
|
| +.line {
|
| + color: #aaaaaa;
|
| +}
|
| +.nop {
|
| + color: #aaaaaa;
|
| +}
|
| +.unimportant {
|
| + color: #cccccc;
|
| +}
|
| +.disasmloc {
|
| + color: #000000;
|
| +}
|
| +.deadsrc {
|
| + cursor: pointer;
|
| +}
|
| +.deadsrc:hover {
|
| + background-color: #eeeeee;
|
| +}
|
| +.livesrc {
|
| + color: #0000ff;
|
| + cursor: pointer;
|
| +}
|
| +.livesrc:hover {
|
| + background-color: #eeeeee;
|
| +}
|
| +.asm {
|
| + color: #008800;
|
| + display: none;
|
| +}
|
| +</style>
|
| +<script type="text/javascript">
|
| +function pprof_toggle_asm(e) {
|
| + var target;
|
| + if (!e) e = window.event;
|
| + if (e.target) target = e.target;
|
| + else if (e.srcElement) target = e.srcElement;
|
| +
|
| + if (target) {
|
| + var asm = target.nextSibling;
|
| + if (asm && asm.className == "asm") {
|
| + asm.style.display = (asm.style.display == "block" ? "" : "block");
|
| + e.preventDefault();
|
| + return false;
|
| + }
|
| + }
|
| +}
|
| +</script>
|
| +</head>
|
| +<body>
|
| +EOF
|
| +}
|
| +
|
| +sub HtmlListingFooter {
|
| + return <<'EOF';
|
| +</body>
|
| +</html>
|
| +EOF
|
| +}
|
| +
|
| +sub HtmlEscape {
|
| + my $text = shift;
|
| + $text =~ s/&/&/g;
|
| + $text =~ s/</</g;
|
| + $text =~ s/>/>/g;
|
| + return $text;
|
| }
|
|
|
| # Returns the indentation of the line, if it has any non-whitespace
|
| @@ -1362,6 +1488,45 @@ sub Indentation {
|
| }
|
| }
|
|
|
| +# If the symbol table contains inlining info, Disassemble() may tag an
|
| +# instruction with a location inside an inlined function. But for
|
| +# source listings, we prefer to use the location in the function we
|
| +# are listing. So use MapToSymbols() to fetch full location
|
| +# information for each instruction and then pick out the first
|
| +# location from a location list (location list contains callers before
|
| +# callees in case of inlining).
|
| +#
|
| +# After this routine has run, each entry in $instructions contains:
|
| +# [0] start address
|
| +# [1] filename for function we are listing
|
| +# [2] line number for function we are listing
|
| +# [3] disassembly
|
| +# [4] limit address
|
| +# [5] most specific filename (may be different from [1] due to inlining)
|
| +# [6] most specific line number (may be different from [2] due to inlining)
|
| +sub GetTopLevelLineNumbers {
|
| + my ($lib, $offset, $instructions) = @_;
|
| + my $pcs = [];
|
| + for (my $i = 0; $i <= $#{$instructions}; $i++) {
|
| + push(@{$pcs}, $instructions->[$i]->[0]);
|
| + }
|
| + my $symbols = {};
|
| + MapToSymbols($lib, $offset, $pcs, $symbols);
|
| + for (my $i = 0; $i <= $#{$instructions}; $i++) {
|
| + my $e = $instructions->[$i];
|
| + push(@{$e}, $e->[1]);
|
| + push(@{$e}, $e->[2]);
|
| + my $addr = $e->[0];
|
| + my $sym = $symbols->{$addr};
|
| + if (defined($sym)) {
|
| + if ($#{$sym} >= 2 && $sym->[1] =~ m/^(.*):(\d+)$/) {
|
| + $e->[1] = $1; # File name
|
| + $e->[2] = $2; # Line number
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| # Print source-listing for one routine
|
| sub PrintSource {
|
| my $prog = shift;
|
| @@ -1371,9 +1536,12 @@ sub PrintSource {
|
| my $cumulative = shift;
|
| my $start_addr = shift;
|
| my $end_addr = shift;
|
| + my $html = shift;
|
| + my $output = shift;
|
|
|
| # Disassemble all instructions (just to get line numbers)
|
| my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
|
| + GetTopLevelLineNumbers($prog, $offset, \@instructions);
|
|
|
| # Hack 1: assume that the first source file encountered in the
|
| # disassembly contains the routine
|
| @@ -1386,7 +1554,7 @@ sub PrintSource {
|
| }
|
| if (!defined($filename)) {
|
| print STDERR "no filename found in $routine\n";
|
| - return;
|
| + return 0;
|
| }
|
|
|
| # Hack 2: assume that the largest line number from $filename is the
|
| @@ -1419,7 +1587,7 @@ sub PrintSource {
|
| {
|
| if (!open(FILE, "<$filename")) {
|
| print STDERR "$filename: $!\n";
|
| - return;
|
| + return 0;
|
| }
|
| my $l = 0;
|
| my $first_indentation = -1;
|
| @@ -1447,12 +1615,24 @@ sub PrintSource {
|
| # Assign all samples to the range $firstline,$lastline,
|
| # Hack 4: If an instruction does not occur in the range, its samples
|
| # are moved to the next instruction that occurs in the range.
|
| - my $samples1 = {};
|
| - my $samples2 = {};
|
| - my $running1 = 0; # Unassigned flat counts
|
| - my $running2 = 0; # Unassigned cumulative counts
|
| - my $total1 = 0; # Total flat counts
|
| - my $total2 = 0; # Total cumulative counts
|
| + my $samples1 = {}; # Map from line number to flat count
|
| + my $samples2 = {}; # Map from line number to cumulative count
|
| + my $running1 = 0; # Unassigned flat counts
|
| + my $running2 = 0; # Unassigned cumulative counts
|
| + my $total1 = 0; # Total flat counts
|
| + my $total2 = 0; # Total cumulative counts
|
| + my %disasm = (); # Map from line number to disassembly
|
| + my $running_disasm = ""; # Unassigned disassembly
|
| + my $skip_marker = "---\n";
|
| + if ($html) {
|
| + $skip_marker = "";
|
| + for (my $l = $firstline; $l <= $lastline; $l++) {
|
| + $disasm{$l} = "";
|
| + }
|
| + }
|
| + my $last_dis_filename = '';
|
| + my $last_dis_linenum = -1;
|
| + my $last_touched_line = -1; # To detect gaps in disassembly for a line
|
| foreach my $e (@instructions) {
|
| # Add up counts for all address that fall inside this instruction
|
| my $c1 = 0;
|
| @@ -1461,6 +1641,38 @@ sub PrintSource {
|
| $c1 += GetEntry($flat, $a);
|
| $c2 += GetEntry($cumulative, $a);
|
| }
|
| +
|
| + if ($html) {
|
| + my $dis = sprintf(" %6s %6s \t\t%8s: %s ",
|
| + HtmlPrintNumber($c1),
|
| + HtmlPrintNumber($c2),
|
| + UnparseAddress($offset, $e->[0]),
|
| + CleanDisassembly($e->[3]));
|
| +
|
| + # Append the most specific source line associated with this instruction
|
| + if (length($dis) < 80) { $dis .= (' ' x (80 - length($dis))) };
|
| + $dis = HtmlEscape($dis);
|
| + my $f = $e->[5];
|
| + my $l = $e->[6];
|
| + if ($f ne $last_dis_filename) {
|
| + $dis .= sprintf("<span class=disasmloc>%s:%d</span>",
|
| + HtmlEscape(CleanFileName($f)), $l);
|
| + } elsif ($l ne $last_dis_linenum) {
|
| + # De-emphasize the unchanged file name portion
|
| + $dis .= sprintf("<span class=unimportant>%s</span>" .
|
| + "<span class=disasmloc>:%d</span>",
|
| + HtmlEscape(CleanFileName($f)), $l);
|
| + } else {
|
| + # De-emphasize the entire location
|
| + $dis .= sprintf("<span class=unimportant>%s:%d</span>",
|
| + HtmlEscape(CleanFileName($f)), $l);
|
| + }
|
| + $last_dis_filename = $f;
|
| + $last_dis_linenum = $l;
|
| + $running_disasm .= $dis;
|
| + $running_disasm .= "\n";
|
| + }
|
| +
|
| $running1 += $c1;
|
| $running2 += $c2;
|
| $total1 += $c1;
|
| @@ -1475,23 +1687,49 @@ sub PrintSource {
|
| AddEntry($samples2, $line, $running2);
|
| $running1 = 0;
|
| $running2 = 0;
|
| + if ($html) {
|
| + if ($line != $last_touched_line && $disasm{$line} ne '') {
|
| + $disasm{$line} .= "\n";
|
| + }
|
| + $disasm{$line} .= $running_disasm;
|
| + $running_disasm = '';
|
| + $last_touched_line = $line;
|
| + }
|
| }
|
| }
|
|
|
| # Assign any leftover samples to $lastline
|
| AddEntry($samples1, $lastline, $running1);
|
| AddEntry($samples2, $lastline, $running2);
|
| -
|
| - printf("ROUTINE ====================== %s in %s\n" .
|
| - "%6s %6s Total %s (flat / cumulative)\n",
|
| - ShortFunctionName($routine),
|
| - $filename,
|
| - Units(),
|
| - Unparse($total1),
|
| - Unparse($total2));
|
| + if ($html) {
|
| + if ($lastline != $last_touched_line && $disasm{$lastline} ne '') {
|
| + $disasm{$lastline} .= "\n";
|
| + }
|
| + $disasm{$lastline} .= $running_disasm;
|
| + }
|
| +
|
| + if ($html) {
|
| + printf $output (
|
| + "<h1>%s</h1>%s\n<pre onClick=\"pprof_toggle_asm()\">\n" .
|
| + "Total:%6s %6s (flat / cumulative %s)\n",
|
| + HtmlEscape(ShortFunctionName($routine)),
|
| + HtmlEscape(CleanFileName($filename)),
|
| + Unparse($total1),
|
| + Unparse($total2),
|
| + Units());
|
| + } else {
|
| + printf $output (
|
| + "ROUTINE ====================== %s in %s\n" .
|
| + "%6s %6s Total %s (flat / cumulative)\n",
|
| + ShortFunctionName($routine),
|
| + CleanFileName($filename),
|
| + Unparse($total1),
|
| + Unparse($total2),
|
| + Units());
|
| + }
|
| if (!open(FILE, "<$filename")) {
|
| print STDERR "$filename: $!\n";
|
| - return;
|
| + return 0;
|
| }
|
| my $l = 0;
|
| while (<FILE>) {
|
| @@ -1501,16 +1739,47 @@ sub PrintSource {
|
| (($l <= $oldlastline + 5) || ($l <= $lastline))) {
|
| chop;
|
| my $text = $_;
|
| - if ($l == $firstline) { printf("---\n"); }
|
| - printf("%6s %6s %4d: %s\n",
|
| - UnparseAlt(GetEntry($samples1, $l)),
|
| - UnparseAlt(GetEntry($samples2, $l)),
|
| - $l,
|
| - $text);
|
| - if ($l == $lastline) { printf("---\n"); }
|
| + if ($l == $firstline) { print $output $skip_marker; }
|
| + my $n1 = GetEntry($samples1, $l);
|
| + my $n2 = GetEntry($samples2, $l);
|
| + if ($html) {
|
| + # Emit a span that has one of the following classes:
|
| + # livesrc -- has samples
|
| + # deadsrc -- has disassembly, but with no samples
|
| + # nop -- has no matching disasembly
|
| + # Also emit an optional span containing disassembly.
|
| + my $dis = $disasm{$l};
|
| + my $asm = "";
|
| + if (defined($dis) && $dis ne '') {
|
| + $asm = "<span class=\"asm\">" . $dis . "</span>";
|
| + }
|
| + my $source_class = (($n1 + $n2 > 0)
|
| + ? "livesrc"
|
| + : (($asm ne "") ? "deadsrc" : "nop"));
|
| + printf $output (
|
| + "<span class=\"line\">%5d</span> " .
|
| + "<span class=\"%s\">%6s %6s %s</span>%s\n",
|
| + $l, $source_class,
|
| + HtmlPrintNumber($n1),
|
| + HtmlPrintNumber($n2),
|
| + HtmlEscape($text),
|
| + $asm);
|
| + } else {
|
| + printf $output(
|
| + "%6s %6s %4d: %s\n",
|
| + UnparseAlt($n1),
|
| + UnparseAlt($n2),
|
| + $l,
|
| + $text);
|
| + }
|
| + if ($l == $lastline) { print $output $skip_marker; }
|
| };
|
| }
|
| close(FILE);
|
| + if ($html) {
|
| + print $output "</pre>\n";
|
| + }
|
| + return 1;
|
| }
|
|
|
| # Return the source line for the specified file/linenumber.
|
| @@ -1653,21 +1922,11 @@ sub PrintDisassembledFunction {
|
| # Print disassembly
|
| for (my $x = $first_inst; $x <= $last_inst; $x++) {
|
| my $e = $instructions[$x];
|
| - my $address = $e->[0];
|
| - $address = AddressSub($address, $offset); # Make relative to section
|
| - $address =~ s/^0x//;
|
| - $address =~ s/^0*//;
|
| -
|
| - # Trim symbols
|
| - my $d = $e->[3];
|
| - while ($d =~ s/\([^()%]*\)(\s*const)?//g) { } # Argument types, not (%rax)
|
| - while ($d =~ s/(\w+)<[^<>]*>/$1/g) { } # Remove template arguments
|
| -
|
| printf("%6s %6s %8s: %6s\n",
|
| UnparseAlt($flat_count[$x]),
|
| UnparseAlt($cum_count[$x]),
|
| - $address,
|
| - $d);
|
| + UnparseAddress($offset, $e->[0]),
|
| + CleanDisassembly($e->[3]));
|
| }
|
| }
|
| }
|
| @@ -2326,6 +2585,16 @@ sub UnparseAlt {
|
| }
|
| }
|
|
|
| +# Alternate pretty-printed form: 0 maps to ""
|
| +sub HtmlPrintNumber {
|
| + my $num = shift;
|
| + if ($num == 0) {
|
| + return "";
|
| + } else {
|
| + return Unparse($num);
|
| + }
|
| +}
|
| +
|
| # Return output units
|
| sub Units {
|
| if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
|
| @@ -2482,6 +2751,13 @@ sub RemoveUninterestingFrames {
|
| '__builtin_vec_new',
|
| 'operator new',
|
| 'operator new[]',
|
| + # The entry to our memory-allocation routines on OS X
|
| + 'malloc_zone_malloc',
|
| + 'malloc_zone_calloc',
|
| + 'malloc_zone_valloc',
|
| + 'malloc_zone_realloc',
|
| + 'malloc_zone_memalign',
|
| + 'malloc_zone_free',
|
| # These mark the beginning/end of our custom sections
|
| '__start_google_malloc',
|
| '__stop_google_malloc',
|
| @@ -3976,7 +4252,7 @@ sub ParseLibraries {
|
| my $finish;
|
| my $offset;
|
| my $lib;
|
| - if ($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+\.(so|dll|dylib|bundle)((\.\d+)+\w*(\.\d+){0,3})?)$/i) {
|
| + if ($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+(\.(so|dll|dylib|bundle)|chrome)((\.\d+)+\w*(\.\d+){0,3})?)$/i) {
|
| # Full line from /proc/self/maps. Example:
|
| # 40000000-40015000 r-xp 00000000 03:01 12845071 /lib/ld-2.3.2.so
|
| $start = HexExtend($1);
|
| @@ -3997,7 +4273,6 @@ sub ParseLibraries {
|
|
|
| # Expand "$build" variable if available
|
| $lib =~ s/\$build\b/$buildvar/g;
|
| -
|
| $lib = FindLibrary($lib);
|
|
|
| # Check for pre-relocated libraries, which use pre-relocated symbol tables
|
| @@ -4414,6 +4689,31 @@ sub ShortFunctionName {
|
| return $function;
|
| }
|
|
|
| +# Trim overly long symbols found in disassembler output
|
| +sub CleanDisassembly {
|
| + my $d = shift;
|
| + while ($d =~ s/\([^()%]*\)(\s*const)?//g) { } # Argument types, not (%rax)
|
| + while ($d =~ s/(\w+)<[^<>]*>/$1/g) { } # Remove template arguments
|
| + return $d;
|
| +}
|
| +
|
| +# Clean file name for display
|
| +sub CleanFileName {
|
| + my ($f) = @_;
|
| + $f =~ s|^/proc/self/cwd/||;
|
| + $f =~ s|^\./||;
|
| + return $f;
|
| +}
|
| +
|
| +# Make address relative to section and clean up for display
|
| +sub UnparseAddress {
|
| + my ($offset, $address) = @_;
|
| + $address = AddressSub($address, $offset);
|
| + $address =~ s/^0x//;
|
| + $address =~ s/^0*//;
|
| + return $address;
|
| +}
|
| +
|
| ##### Miscellaneous #####
|
|
|
| # Find the right versions of the above object tools to use. The
|
|
|