6 if (grep ($_ eq '-h' || $_ eq '--help', @ARGV)) {
7 print "backtrace, for converting raw addresses into symbolic backtraces\n";
9 print "usage: backtrace BINARY ADDRESS...\n";
10 print "where BINARY is the binary file from which to obtain symbols\n";
11 print " and each ADDRESS is a raw address to convert to a symbol name.\n";
13 print "In use with Pintos, BINARY is usually kernel.o and the ADDRESS\n";
14 print "list is taken from the \"Call stack:\" printed by the kernel.\n";
15 print "Read \"Backtraces\" in the \"Debugging Tools\" chapter\n";
16 print "of the Pintos documentation for more information.\n";
19 die "backtrace: binary file argument required (use --help for help)\n"
21 die "backtrace: at least one address argument required (use --help for help)\n"
25 my ($bin) = shift @ARGV;
26 die "backtrace: $bin: not found (use --help for help)\n"
30 my ($a2l) = search_path ("i386-elf-addr2line") || search_path ("addr2line");
32 die "backtrace: neither `i386-elf-addr2line' nor `addr2line' in PATH\n";
36 for my $dir (split (':', $ENV{PATH})) {
37 my ($file) = "$dir/$target";
38 return $file if -e $file;
43 # Drop leading and trailing garbage inserted by kernel.
44 shift while grep (/call|stack/i, $ARGV[0]);
45 s/\.$// foreach @ARGV;
48 open (A2L, "$a2l -fe $bin " . join (' ', @ARGV) . "|");
50 my ($function, $line);
51 chomp ($function = $_);
52 chomp ($line = <A2L>);
53 print shift (@ARGV), ": $function ($line)\n";