Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gtasko/9921047 to your computer and use it in GitHub Desktop.
Save gtasko/9921047 to your computer and use it in GitHub Desktop.
# run atos
sub symbolize_frames {
my ($images,$bt) = @_;
# create mapping of framework => address => bt frame (adjust for slid)
# and for framework => arch
my %frames_to_lookup = ();
my %arch_map = ();
my %base_map = ();
for my $k (keys %$bt) {
my $frame = $$bt{$k};
my $lib = $$images{$$frame{bundle}};
unless($lib) {
# don't know about it, can't symbol
# should have already been warned about this!
# print "Skipping unknown $$frame{bundle}\n";
delete $$bt{$k};
next;
}
# list of address to lookup, mapped to the frame object, for
# each library
$frames_to_lookup{$$lib{symbol}}{$$frame{address}} = $frame;
$arch_map{$$lib{symbol}} = $$lib{arch};
$base_map{$$lib{symbol}} = $$lib{base};
}
# run atos for each library
while(my($symbol,$frames) = each(%frames_to_lookup)) {
# escape the symbol path if it contains single quotes
my $escapedSymbol = $symbol;
$escapedSymbol =~ s/\'/\'\\'\'/g;
# run atos with the addresses and binary files we just gathered
my $arch = $arch_map{$symbol};
my $base = $base_map{$symbol};
my $cmd = "$atos -arch $arch -l $base -o '$escapedSymbol' @{[ keys %$frames ]} | ";
print STDERR "Running $cmd\n" if $opt{v};
open my($ph),$cmd or die $!;
my @symbolled_frames = map { chomp; $_ } <$ph>;
close $ph or die $!;
my $references = 0;
foreach my $symbolled_frame (@symbolled_frames) {
$symbolled_frame =~ s/\s*\(in .*?\)//; # clean up -- don't need to repeat the lib here
# find the correct frame -- the order should match since we got the address list with keys
my ($k,$frame) = each(%$frames);
if ( $symbolled_frame !~ /^\d/ ) {
# only symbolicate if we fetched something other than an address
#re-increment any offset that we had to artifically decrement
if($$frame{raw_address} ne $$frame{address}) {
$symbolled_frame =~ s|(.+ \+) (\d+)|$1." ".($2 + 1)|e;
}
$$frame{symbolled} = $symbolled_frame;
$references++;
}
}
if ( $references == 0 ) {
print STDERR "## Warning: Unable to symbolicate from required binary: $symbol\n";
}
}
# just run through and remove elements for which we didn't find a
# new mapping:
while(my($k,$v) = each(%$bt)) {
delete $$bt{$k} unless defined $$v{symbolled};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment