Get rid of DEBUG macro, supporting code, and documentation,
[pintos-anon] / doc / debug.texi
index 19270f46e46c19aa4d8897195a68622af032b913..75d9b242a79b12dfbb0496d4d962e538a0259d98 100644 (file)
@@ -7,10 +7,10 @@ introduces you to a few of them.
 @menu
 * printf::                      
 * ASSERT::                      
-* DEBUG::                       
 * UNUSED NO_RETURN NO_INLINE PRINTF_FORMAT::  
 * Backtraces::                  
 * i386-elf-gdb::                
+* Debugging by Infinite Loop::  
 * Modifying Bochs::             
 * Debugging Tips::              
 @end menu
@@ -52,31 +52,6 @@ When an assertion proves untrue, the kernel panics.  The panic message
 should help you to find the problem.  See the description of
 backtraces below for more information.
 
-@node DEBUG
-@section @code{DEBUG}
-
-The @code{DEBUG} macro, also defined in @file{<debug.h>}, is a sort of
-conditional @func{printf}.  It takes as its arguments the name of a
-``message class'' and a @func{printf}-like format string and
-arguments.  The message class is used to filter the messages that are
-actually displayed.  You select the messages to display on the Pintos
-command line using the @option{-d} option.  This allows you to easily
-turn different types of messages on and off while you debug, without
-the need to recompile.
-
-For example, suppose you want to output thread debugging messages.  To
-use a class named @code{thread}, you could invoke @code{DEBUG} like
-this:
-@example
-DEBUG(thread, "thread id: %d\n", id);
-@end example
-@noindent
-and then to start Pintos with @code{thread} messages enable you'd use
-a command line like this:
-@example
-pintos run -d thread
-@end example
-
 @node UNUSED NO_RETURN NO_INLINE PRINTF_FORMAT
 @section UNUSED, NO_RETURN, NO_INLINE, and PRINTF_FORMAT
 
@@ -131,7 +106,7 @@ we've supplied a wrapper for it simply called @command{backtrace}.
 Give it the name of your @file{kernel.o} as the first argument and the
 hexadecimal numbers composing the backtrace (including the @samp{0x}
 prefixes) as the remaining arguments.  It outputs the function name
-and source file line numbers that correspond to each address.
+and source file line numbers that correspond to each address.  
 
 If the translated form of a backtrace is garbled, or doesn't make
 sense (e.g.@: function A is listed above function B, but B doesn't
@@ -141,13 +116,121 @@ Alternatively, it could be that the @file{kernel.o} you passed to
 @command{backtrace} does not correspond to the kernel that produced
 the backtrace.
 
+@menu
+* Backtrace Example::           
+@end menu
+
+@node Backtrace Example
+@subsection Example
+
+Here's an example.  Suppose that Pintos printed out this following call
+stack, which is taken from an actual Pintos submission for the file
+system project:
+
+@example
+Call stack: 0xc0106eff 0xc01102fb 0xc010dc22 0xc010cf67 0xc0102319
+0xc010325a 0x804812c 0x8048a96 0x8048ac8.
+@end example
+
+You would then invoke the @command{backtrace} utility like shown below,
+cutting and pasting the backtrace information into the command line.
+This assumes that @file{kernel.o} is in the current directory.  You
+would of course enter all of the following on a single shell command
+line:
+
+@example
+backtrace kernel.o 0xc0106eff 0xc01102fb 0xc010dc22 0xc010cf67 0xc0102319
+0xc010325a 0x804812c 0x8048a96 0x8048ac8
+@end example
+
+The backtrace output would then look something like this:
+
+@example
+0xc0106eff: debug_panic (../../lib/debug.c:86)
+0xc01102fb: file_seek (../../filesys/file.c:405)
+0xc010dc22: seek (../../userprog/syscall.c:744)
+0xc010cf67: syscall_handler (../../userprog/syscall.c:444)
+0xc0102319: intr_handler (../../threads/interrupt.c:334)
+0xc010325a: ?? (threads/intr-stubs.S:1554)
+0x804812c: ?? (??:0)
+0x8048a96: ?? (??:0)
+0x8048ac8: ?? (??:0)
+@end example
+
+(You will probably not get the same results if you run the command above
+on your own kernel binary, because the source code you compiled from is
+different from the source code that emitted the panic message.)
+
+The first line in the backtrace refers to @func{debug_panic}, the
+function that implements kernel panics.  Because backtraces commonly
+result from kernel panics, @func{debug_panic} will often be the first
+function shown in a backtrace.
+
+The second line shows @func{file_seek} to be the function that panicked,
+in this case as the result of an assertion failure.  In the source code
+tree used for this example, line 405 of @file{filesys/file.c} is the
+assertion
+
+@example
+ASSERT (file_ofs >= 0);
+@end example
+
+@noindent
+Thus, @func{file_seek} panicked because it passed a negative file offset
+argument.
+
+The third line indicates that @func{seek} called @func{file_seek},
+presumably without validating the offset argument.  In this submission,
+@func{seek} implements the @code{seek} system call.
+
+The fourth line shows that @func{syscall_handler}, the system call
+handler, invoked @func{seek}.
+
+The fifth and sixth lines are the interrupt handler entry path.
+
+The remaining lines are for addresses below @code{PHYS_BASE}.  This
+means that they refer to addresses in the user program, not in the
+kernel.  If you know what user program was running when the kernel
+panicked, you can re-run @command{backtrace} on the user program, like
+so: (typing the command on a single line, of course):
+
+@example
+backtrace grow-too-big 0xc0106eff 0xc01102fb 0xc010dc22 0xc010cf67
+0xc0102319 0xc010325a 0x804812c 0x8048a96 0x8048ac8
+@end example
+
+The results look like this:
+
+@example
+0xc0106eff: ?? (??:0)
+0xc01102fb: ?? (??:0)
+0xc010dc22: ?? (??:0)
+0xc010cf67: ?? (??:0)
+0xc0102319: ?? (??:0)
+0xc010325a: ?? (??:0)
+0x804812c: test_main (/home/blp/cs140/pintos/grading/filesys/grow-too-big.c:20)
+0x8048a96: main (/home/blp/cs140/pintos/grading/filesys/fsmain.c:10)
+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}
 
 You can run the Pintos kernel under the supervision of the
 @command{i386-elf-gdb} debugger.@footnote{If you're using an
 80@var{x}86 system for development, it's probably just called
-@command{addr2line}.}  There are two steps in the process.  First,
+@command{gdb}.}  There are two steps in the process.  First,
 start Pintos with the @option{--gdb} option, e.g.@: @command{pintos
 --gdb run}.  Second, in a second terminal, invoke @command{gdb} on
 @file{kernel.o}:
@@ -201,14 +284,6 @@ address.
 (Use a @samp{0x} prefix to specify an address in hex.)
 @end table
 
-You might notice that @command{gdb} tends to show code being executed
-in an order different from the order in the source.  That is, the
-current statement jumps around seemingly randomly.  This is due to
-GCC's optimizer, which does tend to reorder code.  If it bothers you,
-you can turn off optimization by editing
-@file{pintos/src/Make.config}, removing @option{-O3} from the
-@code{CFLAGS} definition.
-
 If you notice other strange behavior while using @command{gdb}, there
 are three possibilities.  The first is that there is a bug in your
 modified Pintos.  The second is that there is a bug in Bochs's
@@ -217,6 +292,38 @@ that there is a bug in the original Pintos code.  The first and second
 are quite likely, and you should seriously consider both.  We hope
 that the third is less likely, but it is also possible.
 
+@node Debugging by Infinite Loop
+@section Debugging by Infinite Loop
+
+If you get yourself into a situation where the machine reboots in a
+loop, you've probably hit a ``triple fault.''  In such a situation you
+might not be able to use @func{printf} for debugging, because the
+reboots might be happening even before everything needed for
+@func{printf} is initialized.  In such a situation, you might want to
+try what I call ``debugging by infinite loop.''
+
+What you do is pick a place in the Pintos code, insert the statement
+@code{for (;;);} there, and recompile and run.  There are two likely
+possibilities:
+
+@itemize @bullet
+@item
+The machine hangs without rebooting.  If this happens, you know that
+the infinite loop is running.  That means that whatever caused the
+problem must be @emph{after} the place you inserted the infinite loop.
+Now move the infinite loop later in the code sequence.
+
+@item
+The machine reboots in a loop.  If this happens, you know that the
+machine didn't make it to the infinite loop.  Thus, whatever caused the
+reboot must be @emph{before} the place you inserted the infinite loop.
+Now move the infinite loop earlier in the code sequence.
+@end itemize
+
+If you move around the infinite loop in a ``binary search'' fashion, you
+can use this technique to pin down the exact spot that everything goes
+wrong.  It should only take a few minutes at most.
+
 @node Modifying Bochs
 @section Modifying Bochs
 
@@ -251,17 +358,18 @@ above, a good place to start adding @func{printf}s is
 @node Debugging Tips
 @section Tips
 
-The page allocator in @file{threads/palloc.c} clears all the bytes in
-pages to @t{0xcc} when they are freed.  Thus, if you see an attempt to
+The page allocator in @file{threads/palloc.c} and the block allocator in
+@file{threads/malloc.c} both clear all the bytes in pages and blocks to
+@t{0xcc} when they are freed.  Thus, if you see an attempt to
 dereference a pointer like @t{0xcccccccc}, or some other reference to
 @t{0xcc}, there's a good chance you're trying to reuse a page that's
-already been freed.  Also, byte @t{0xcc} is the CPU opcode for
-``invoke interrupt 3,'' so if you see an error like @code{Interrupt
-0x03 (#BP Breakpoint Exception)}, Pintos tried to execute code in a
-freed page.
-
-Similarly, the block allocator in @file{threads/malloc.c} clears all
-the bytes in freed blocks to @t{0xcd}.  The two bytes @t{0xcdcd} are
-a CPU opcode for ``invoke interrupt @t{0xcd},'' so @code{Interrupt
-0xcd (unknown)} is a good sign that you tried to execute code in a
-block freed with @func{free}.
+already been freed.  Also, byte @t{0xcc} is the CPU opcode for ``invoke
+interrupt 3,'' so if you see an error like @code{Interrupt 0x03 (#BP
+Breakpoint Exception)}, Pintos tried to execute code in a freed page or
+block.
+
+An assertion failure on the expression @code{sec_no < d->capacity}
+indicates that Pintos tried to access a file through an inode that has
+been closed and freed.  Freeing an inode clears its starting sector
+number to @t{0xcccccccc}, which is not a valid sector number for disks
+smaller than about 1.6 TB.