How to debug user programs with gdb.
[pintos-anon] / doc / debug.texi
index 35e7c4af5e9e0fcb1caf8afa9f8867f898b5796e..389080d39f0cf2e36be46ec5ad4b907c6502ceed 100644 (file)
@@ -7,7 +7,6 @@ introduces you to a few of them.
 @menu
 * printf::                      
 * ASSERT::                      
-* DEBUG::                       
 * UNUSED NO_RETURN NO_INLINE PRINTF_FORMAT::  
 * Backtraces::                  
 * i386-elf-gdb::                
@@ -53,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
 
@@ -198,7 +172,7 @@ tree used for this example, line 405 of @file{filesys/file.c} is the
 assertion
 
 @example
-ASSERT (file_ofs >= )0;
+ASSERT (file_ofs >= 0);
 @end example
 
 @noindent
@@ -217,18 +191,12 @@ 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.  You
-need to have compiled the user program with debug symbols enabled for
-this to be useful.  Instructions for doing so are included in
-@file{pintos/src/Makefile.userprog}.
-
-In this case, we rerun @command{backtrace} like so (typing the command
-on a single line, of course):
+panicked, you can re-run @command{backtrace} on the user program, like
+so: (typing the command on a single line, of course):
 
 @example
-~/cs140/pintos/src/utils/backtrace grow-too-big 0xc0106eff 0xc01102fb
-0xc010dc22 0xc010cf67 0xc0102319 0xc010325a 0x804812c 0x8048a96
-0x8048ac8
+backtrace grow-too-big 0xc0106eff 0xc01102fb 0xc010dc22 0xc010cf67
+0xc0102319 0xc010325a 0x804812c 0x8048a96 0x8048ac8
 @end example
 
 The results look like this:
@@ -245,13 +213,24 @@ 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}
 
 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}:
@@ -305,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
@@ -321,6 +292,22 @@ 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.
 
+You can also use @command{gdb} to debug a user program running under
+Pintos.  Start by issuing this @command{gdb} command to load the
+program's symbol table:
+@example
+add-symbol-file @var{program}
+@end example
+where @var{program} is the name of the program's executable (in the host
+file system, not in the Pintos file system).  After this, you should be
+able to debug the user program the same way you would the kernel, by
+placing breakpoints, inspecting data, etc.  Your actions apply to every
+user program running in Pintos, not just to the one you want to debug,
+so be careful in interpreting the results.  Also, a name that appears in
+both the kernel and the user program will actually refer to the kernel
+name.  (The latter problem can be avoided by giving the user executable
+name on the @command{gdb} command line, instead of @file{kernel.o}.)
+
 @node Debugging by Infinite Loop
 @section Debugging by Infinite Loop
 
@@ -387,17 +374,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.