* printf::
* ASSERT::
* DEBUG::
+* UNUSED NO_RETURN NO_INLINE PRINTF_FORMAT::
* Backtraces::
* i386-elf-gdb::
+* Debugging by Infinite Loop::
* Modifying Bochs::
* Debugging Tips::
@end menu
@node printf
-@section @func{printf}
+@section @code{@code{printf()}}
Don't underestimate the value of @func{printf}. The way
@func{printf} is implemented in Pintos, you can call it from
Assertions are useful because they can catch problems early, before
they'd otherwise be notices. Pintos provides a macro for assertions
-named @code{ASSERT}, defined in @code{<debug.h>}, that you can use for
+named @code{ASSERT}, defined in @file{<debug.h>}, that you can use for
this purpose. Ideally, each function should begin with a set of
assertions that check its arguments for validity. (Initializers for
functions' local variables are evaluated before assertions are
@node DEBUG
@section @code{DEBUG}
-The @code{DEBUG} macro, also defined in @code{<debug.h>}, is a sort of
+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
pintos run -d thread
@end example
+@node UNUSED NO_RETURN NO_INLINE PRINTF_FORMAT
+@section UNUSED, NO_RETURN, NO_INLINE, and PRINTF_FORMAT
+
+These macros defined in @file{<debug.h>} tell the compiler special
+attributes of a function or function parameter. Their expansions are
+GCC-specific.
+
+@defmac UNUSED
+Appended to a function parameter to tell the compiler that the
+parameter might not be used within the function. It suppresses the
+warning that would otherwise appear.
+@end defmac
+
+@defmac NO_RETURN
+Appended to a function prototype to tell the compiler that the
+function never returns. It allows the compiler to fine-tune its
+warnings and its code generation.
+@end defmac
+
+@defmac NO_INLINE
+Appended to a function prototype to tell the compiler to never emit
+the function in-line. Occasionally useful to improve the quality of
+backtraces (see below).
+@end defmac
+
+@defmac PRINTF_FORMAT (@var{format}, @var{first})
+Appended to a function prototype to tell the compiler that the
+function takes a @func{printf}-like format string as its
+@var{format}th argument and that the corresponding value arguments
+start at the @var{first}th argument. This lets the compiler tell you
+if you pass the wrong argument types.
+@end defmac
+
@node Backtraces
@section Backtraces
(Use a @samp{0x} prefix to specify an address in hex.)
@end table
-If you notice unexplainable behavior while using @command{gdb}, there
+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
interface to @command{gdb} or in @command{gdb} itself. The third is
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