From eb5ba83c314e0074e2b280516e3e30b8626c638f Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 1 Jan 2005 23:21:51 +0000 Subject: [PATCH] Add a suggestion to use `backtrace' and a reference to the manual to the message printed by debug_panic(). Improve backtrace program. Document improvements. --- doc/debug.texi | 11 ++++++++ src/lib/debug.c | 4 +++ src/utils/backtrace | 61 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/doc/debug.texi b/doc/debug.texi index f93eeda..f36ae4a 100644 --- a/doc/debug.texi +++ b/doc/debug.texi @@ -240,6 +240,17 @@ The results look like this: 0x8048ac8: _start (../../src/lib/user/entry.c:9) @end example +Here's an extra tip for anyone who read this far: @command{backtrace} +is smart enough to strip the @code{Call stack:} header and @samp{.} +trailer from the command line if you include them. This can save you +a little bit of trouble in cutting and pasting. Thus, the following +command prints the same output as the first one we used: + +@example +backtrace kernel.o Call stack: 0xc0106eff 0xc01102fb 0xc010dc22 +0xc010cf67 0xc0102319 0xc010325a 0x804812c 0x8048a96 0x8048ac8. +@end example + @node i386-elf-gdb @section @command{i386-elf-gdb} diff --git a/src/lib/debug.c b/src/lib/debug.c index 6d75e7a..4f0f5f3 100644 --- a/src/lib/debug.c +++ b/src/lib/debug.c @@ -88,6 +88,10 @@ debug_panic (const char *file, int line, const char *function, debug_backtrace (); + printf ("The `backtrace' program can make call stacks useful.\n" + "Read \"Backtraces\" in the \"Debugging Tools\" chapter\n" + "of the Pintos documentation for more information.\n"); + #ifdef KERNEL serial_flush (); if (power_off_when_done) diff --git a/src/utils/backtrace b/src/utils/backtrace index 300df64..487e224 100755 --- a/src/utils/backtrace +++ b/src/utils/backtrace @@ -1,19 +1,56 @@ -#! /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 shift (@ARGV), ": $function ($line)\n"; +#! /usr/bin/perl -w + +use strict; + +# Check command line. +if (grep ($_ eq '-h' || $_ eq '--help', @ARGV)) { + print "backtrace, for converting raw addresses into symbolic backtraces\n"; + print "\n"; + print "usage: backtrace BINARY ADDRESS...\n"; + print "where BINARY is the binary file from which to obtain symbols\n"; + print " and each ADDRESS is a raw address to convert to a symbol name.\n"; + print "\n"; + print "In use with Pintos, BINARY is usually kernel.o and the ADDRESS\n"; + print "list is taken from the \"Call stack:\" printed by the kernel.\n"; + print "Read \"Backtraces\" in the \"Debugging Tools\" chapter\n"; + print "of the Pintos documentation for more information.\n"; + exit 0; +} +die "backtrace: binary file argument required (use --help for help)\n" + if @ARGV == 0; +die "backtrace: at least one address argument required (use --help for help)\n" + if @ARGV == 1; + +# Find binary file. +my ($bin) = shift @ARGV; +die "backtrace: $bin: not found (use --help for help)\n" + if ! -e $bin; + +# 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; } + +# Drop leading and trailing garbage inserted by kernel. +shift while grep (/call|stack/i, $ARGV[0]); +s/\.$// foreach @ARGV; + +# 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); + -- 2.30.2