mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 812070 (part 1) - Merge %pipes and %address_adjustment in fix-linux-stack.pl.
--HG-- extra : rebase_source : db6a782a2e5df081d885b3eb72dcd19e7b196687
This commit is contained in:
parent
a34f0cb71c
commit
bf9f66f195
@ -26,44 +26,49 @@ use File::Basename;
|
||||
# XXX Hard-coded to gdb defaults (works on Fedora).
|
||||
my $global_debug_dir = '/usr/lib/debug';
|
||||
|
||||
# addr2line wants offsets relative to the base address for shared
|
||||
# libraries, but it wants addresses including the base address offset
|
||||
# for executables. This function returns the appropriate address
|
||||
# adjustment to add to an offset within file. See bug 230336.
|
||||
my %address_adjustments;
|
||||
sub address_adjustment($) {
|
||||
my ($file) = @_;
|
||||
unless (exists $address_adjustments{$file}) {
|
||||
# find out if it's an executable (as opposed to a shared library)
|
||||
my $elftype;
|
||||
open(ELFHDR, '-|', 'readelf', '-h', $file);
|
||||
while (<ELFHDR>) {
|
||||
if (/^\s*Type:\s+(\S+)/) {
|
||||
$elftype = $1;
|
||||
# We record several things for each file encountered.
|
||||
#
|
||||
# - {pipe_read}, {pipe_write}: these constitute a bidirectional pipe to an
|
||||
# addr2line process that gives symbol information for a file.
|
||||
#
|
||||
# - {address_adjustment}: addr2line wants offsets relative to the base address
|
||||
# for shared libraries, but it wants addresses including the base address
|
||||
# offset for executables. This holds the appropriate address adjustment to
|
||||
# add to an offset within file. See bug 230336.
|
||||
#
|
||||
my %file_infos;
|
||||
|
||||
sub set_address_adjustment($$) {
|
||||
my ($file, $file_info) = @_;
|
||||
|
||||
# find out if it's an executable (as opposed to a shared library)
|
||||
my $elftype;
|
||||
open(ELFHDR, '-|', 'readelf', '-h', $file);
|
||||
while (<ELFHDR>) {
|
||||
if (/^\s*Type:\s+(\S+)/) {
|
||||
$elftype = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(ELFHDR);
|
||||
|
||||
# If it's an executable, make adjustment the base address.
|
||||
# Otherwise, leave it zero.
|
||||
my $adjustment = 0;
|
||||
if ($elftype eq 'EXEC') {
|
||||
open(ELFSECS, '-|', 'readelf', '-S', $file);
|
||||
while (<ELFSECS>) {
|
||||
if (/^\s*\[\s*\d+\]\s+\.text\s+\w+\s+(\w+)\s+(\w+)\s+/) {
|
||||
# Subtract the .text section's offset within the
|
||||
# file from its base address.
|
||||
$adjustment = hex($1) - hex($2);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(ELFHDR);
|
||||
|
||||
# If it's an executable, make adjustment the base address.
|
||||
# Otherwise, leave it zero.
|
||||
my $adjustment = 0;
|
||||
if ($elftype eq 'EXEC') {
|
||||
open(ELFSECS, '-|', 'readelf', '-S', $file);
|
||||
while (<ELFSECS>) {
|
||||
if (/^\s*\[\s*\d+\]\s+\.text\s+\w+\s+(\w+)\s+(\w+)\s+/) {
|
||||
# Subtract the .text section's offset within the
|
||||
# file from its base address.
|
||||
$adjustment = hex($1) - hex($2);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(ELFSECS);
|
||||
}
|
||||
|
||||
$address_adjustments{$file} = $adjustment;
|
||||
close(ELFSECS);
|
||||
}
|
||||
return $address_adjustments{$file};
|
||||
|
||||
$file_info->{address_adjustment} = $adjustment;
|
||||
}
|
||||
|
||||
# Files sometimes contain a link to a separate object file that contains
|
||||
@ -191,24 +196,21 @@ sub separate_debug_file_for($) {
|
||||
return '';
|
||||
}
|
||||
|
||||
# Return a reference to a hash whose {read} and {write} entries are a
|
||||
# bidirectional pipe to an addr2line process that gives symbol
|
||||
# information for a file.
|
||||
my %pipes;
|
||||
sub addr2line_pipe($) {
|
||||
sub get_file_info($) {
|
||||
my ($file) = @_;
|
||||
my $pipe;
|
||||
unless (exists $pipes{$file}) {
|
||||
my $file_info = $file_infos{$file};
|
||||
unless (defined $file_info) {
|
||||
my $debug_file = separate_debug_file_for($file);
|
||||
$debug_file = $file if ($debug_file eq '');
|
||||
|
||||
my $pid = open2($pipe->{read}, $pipe->{write},
|
||||
my $pid = open2($file_info->{pipe_read}, $file_info->{pipe_write},
|
||||
'/usr/bin/addr2line', '-C', '-f', '-e', $debug_file);
|
||||
$pipes{$file} = $pipe;
|
||||
} else {
|
||||
$pipe = $pipes{$file};
|
||||
|
||||
set_address_adjustment($file, $file_info);
|
||||
|
||||
$file_infos{$file} = $file_info;
|
||||
}
|
||||
return $pipe;
|
||||
return $file_info;
|
||||
}
|
||||
|
||||
# Ignore SIGPIPE as a workaround for addr2line crashes in some situations.
|
||||
@ -225,11 +227,11 @@ while (<>) {
|
||||
my $after = $5; # allow preservation of counts
|
||||
|
||||
if (-f $file) {
|
||||
my $pipe = addr2line_pipe($file);
|
||||
$address += address_adjustment($file);
|
||||
my $file_info = get_file_info($file);
|
||||
$address += $file_info->{address_adjustment};
|
||||
|
||||
my $out = $pipe->{write};
|
||||
my $in = $pipe->{read};
|
||||
my $out = $file_info->{pipe_write};
|
||||
my $in = $file_info->{pipe_read};
|
||||
printf {$out} "0x%X\n", $address;
|
||||
chomp(my $symbol = <$in>);
|
||||
chomp(my $fileandline = <$in>);
|
||||
|
Loading…
Reference in New Issue
Block a user