X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Futils%2Fbacktrace;h=baa5eff535cd878922e02e0dcaa84a022fce1807;hb=615bf3b3d2a8573ed6fb9ddc0055745e163ac999;hp=0dd28420e3d4cfb38caade7dfdec1913ddc6d4cb;hpb=af08493a52dbd0108d14fae346631f1874320fa8;p=pintos-anon diff --git a/src/utils/backtrace b/src/utils/backtrace index 0dd2842..baa5eff 100755 --- a/src/utils/backtrace +++ b/src/utils/backtrace @@ -1,19 +1,66 @@ -#! /usr/bin/perl -$a2l = search_path ("i386-elf-addr2line") || search_path ("addr2line"); -$bin = shift @ARGV; -open (A2L, "$a2l -fe $bin " . join (' ', @ARGV) . "|"); -while ($function = ) { - $line = ; - chomp $function; - chomp $line; - print "$function ($line)\n"; +#! /usr/bin/perl -w + +use strict; + +# Check command line. +if (grep ($_ eq '-h' || $_ eq '--help', @ARGV)) { + print <<'EOF'; +backtrace, for converting raw addresses into symbolic backtraces +usage: backtrace [BINARY] ADDRESS... +where BINARY is the binary file from which to obtain symbols + and ADDRESS is a raw address to convert to a symbol name. + +If BINARY is unspecified, the default is the first of kernel.o or +build/kernel.o that exists. + +The ADDRESS list should be taken from the "Call stack:" printed by the +kernel. Read "Backtraces" in the "Debugging Tools" chapter of the +Pintos documentation for more information. +EOF + exit 0; +} +die "backtrace: at least one argument required (use --help for help)\n" + if @ARGV == 0; + +# Drop leading and trailing garbage inserted by kernel. +shift while grep (/^(call|stack:?)$/i, $ARGV[0]); +s/\.$// foreach @ARGV; + +# Find binary file. +my ($bin) = $ARGV[0]; +if (-e $bin) { + shift @ARGV; +} elsif ($bin !~ /^0/) { + die "backtrace: $bin: not found (use --help for help)\n"; +} elsif (-e 'kernel.o') { + $bin = 'kernel.o'; +} elsif (-e 'build/kernel.o') { + $bin = 'build/kernel.o'; +} else { + die "backtrace: can't find binary for backtrace (use --help for help)\n"; +} + +# Find addr2line. +my ($a2l) = search_path ("i386-elf-addr2line") || search_path ("addr2line"); +if (!$a2l) { + die "backtrace: neither `i386-elf-addr2line' nor `addr2line' in PATH\n"; } - sub search_path { my ($target) = @_; - for $dir (split (':', $ENV{PATH})) { + for my $dir (split (':', $ENV{PATH})) { my ($file) = "$dir/$target"; return $file if -e $file; } - return 0; + return undef; } + +# Do backtrace. +open (A2L, "$a2l -fe $bin " . join (' ', @ARGV) . "|"); +while () { + my ($function, $line); + chomp ($function = $_); + chomp ($line = ); + print shift (@ARGV), ": $function ($line)\n"; +} +close (A2L); +