Update docs.
[pintos-anon] / doc / debug.texi
1 @node Debugging Tools, , Project Documentation, Top
2 @appendix Debugging Tools
3
4 Many tools lie at your disposal for debugging Pintos.  This appendix
5 introduces you to a few of them.
6
7 @menu
8 * printf::                      
9 * ASSERT::                      
10 * DEBUG::                       
11 * Backtraces::                  
12 * i386-elf-gdb::                
13 * Modifying Bochs::             
14 @end menu
15
16 @node printf
17 @section @code{printf()}
18
19 Don't underestimate the value of @code{printf()}.  The way
20 @code{printf()} is implemented in Pintos, you can call it from
21 practically anywhere in the kernel, whether it's in a kernel thread or
22 an interrupt handler, almost regardless of what locks are held.
23
24 @code{printf()} isn't useful just because it can print data members.
25 It can also help figure out when and where something goes wrong, even
26 when the kernel crashes or panics without a useful error message.  The
27 strategy is to sprinkle calls to @code{print()} with different strings
28 (e.g.@: @code{"1\n"}, @code{"2\n"}, @dots{}) throughout the pieces of
29 code you suspect are failing.  If you don't even see @code{1} printed,
30 then something bad happened before that point, if you see @code{1}
31 but not @code{2}, then something bad happened between those two
32 points, and so on.  Based on what you learn, you can then insert more
33 @code{printf()} calls in the new, smaller region of code you suspect.
34 Eventually you can narrow the problem down to a single statement.
35
36 @node ASSERT
37 @section @code{ASSERT}
38
39 Assertions are useful because they can catch problems early, before
40 they'd otherwise be notices.  Pintos provides a macro for assertions
41 named @code{ASSERT}, defined in @code{<debug.h>}, that you can use for
42 this purpose.  Ideally, each function should begin with a set of
43 assertions that check its arguments for validity.  (Initializers for
44 functions' local variables are evaluated before assertions are
45 checked, so be careful not to assume that an argument is valid in an
46 initializer.)  You can also sprinkle assertions throughout the body of
47 functions in places where you suspect things are likely to go wrong.
48
49 When an assertion proves untrue, the kernel panics.  The panic message
50 should help you to find the problem.  See the description of
51 backtraces below for more information.
52
53 @node DEBUG
54 @section @code{DEBUG}
55
56 The @code{DEBUG} macro, also defined in @code{<debug.h>}, is a sort of
57 conditional @code{printf()}.  It takes as its arguments the name of a
58 ``message class'' and a @code{printf()}-like format string and
59 arguments.  The message class is used to filter the messages that are
60 actually displayed.  You select the messages to display on the Pintos
61 command line using the @option{-d} option.  This allows you to easily
62 turn different types of messages on and off while you debug, without
63 the need to recompile.
64
65 For example, suppose you want to output thread debugging messages.  To
66 use a class named @code{thread}, you could invoke @code{DEBUG} like
67 this:
68 @example
69 DEBUG(thread, "thread id: %d\n", id);
70 @end example
71 @noindent
72 and then to start Pintos with @code{thread} messages enable you'd use
73 a command line like this:
74 @example
75 pintos run -d thread
76 @end example
77
78 @node Backtraces
79 @section Backtraces
80
81 When the kernel panics, it prints a ``backtrace,'' that is, a summary
82 of how your program got where it is, as a list of addresses inside the
83 functions that were running at the time of the panic.  You can also
84 insert a call to @code{debug_backtrace()}, prototyped in
85 @file{<debug.h>}, at any point in your code.
86
87 The addresses in a backtrace are listed as raw hexadecimal numbers,
88 which are meaningless in themselves.  You can translate them into
89 function names and source file line numbers using a tool called
90 @command{i386-elf-addr2line}.@footnote{If you're using an 80@var{x}86
91 system for development, it's probably just called
92 @command{addr2line}.}
93
94 The output format of @command{i386-elf-addr2line} is not ideal, so
95 we've supplied a wrapper for it simply called @command{backtrace}.
96 Give it the name of your @file{kernel.o} as the first argument and the
97 hexadecimal numbers composing the backtrace (including the @samp{0x}
98 prefixes) as the remaining arguments.  It outputs the function name
99 and source file line numbers that correspond to each address.
100
101 If the translated form of a backtrace is garbled, or doesn't make
102 sense (e.g.@: function A is listed above function B, but B doesn't
103 call A), then it's a good sign that you're corrupting a kernel
104 thread's stack, because the backtrace is extracted from the stack.
105 Alternatively, it could be that the @file{kernel.o} you passed to
106 @command{backtrace} does not correspond to the kernel that produced
107 the backtrace.
108
109 @node i386-elf-gdb
110 @section @command{i386-elf-gdb}
111
112 You can run the Pintos kernel under the supervision of the
113 @command{i386-elf-gdb} debugger.@footnote{If you're using an
114 80@var{x}86 system for development, it's probably just called
115 @command{addr2line}.}  There are two steps in the process.  First,
116 start Pintos with the @option{--gdb} option, e.g.@: @command{pintos
117 --gdb run}.  Second, in a second terminal, invoke @command{gdb} on
118 @file{kernel.o}:
119 @example
120 i386-elf-gdb kernel.o
121 @end example
122 @noindent and issue the following @command{gdb} command:
123 @example
124 target remote localhost:1234
125 @end example
126
127 At this point, @command{gdb} is connected to Bochs over a local
128 network connection.  You can now issue any normal @command{gdb}
129 commands.  If you issue the @samp{c} command, the Bochs BIOS will take
130 control, load Pintos, and then Pintos will run in the usual way.  You
131 can pause the process at any point with @key{Ctrl+C}.  If you want
132 @command{gdb} to stop when Pintos starts running, set a breakpoint on
133 @code{main()} with the command @code{break main} before @samp{c}.
134
135 You can read the @command{gdb} manual by typing @code{info gdb} at a
136 terminal command prompt, or you can view it in Emacs with the command
137 @kbd{C-h i}.  Here's a few commonly useful @command{gdb} commands:
138
139 @table @code
140 @item c
141 Continue execution until the next breakpoint or until @key{Ctrl+C} is
142 typed.
143
144 @item break @var{function}
145 @itemx break @var{filename}:@var{linenum}
146 @itemx break *@var{address}
147 Sets a breakpoint at the given function, line number, or address.
148 (Use a @samp{0x} prefix to specify an address in hex.)
149
150 @item p @var{expression}
151 Evaluates the given C expression and prints its value.
152 If the expression contains a function call, the function will actually
153 be executed, so be careful.
154
155 @item l *@var{address}
156 Lists a few lines of code around the given address.
157 (Use a @samp{0x} prefix to specify an address in hex.)
158
159 @item bt
160 Prints a stack backtrace similar to that output by the
161 @command{backtrace} program described above.
162
163 @item p/a @var{address}
164 Prints the name of the function or variable that occupies the given
165 address.
166 (Use a @samp{0x} prefix to specify an address in hex.)
167 @end table
168
169 If you notice unexplainable behavior while using @command{gdb}, there
170 are three possibilities.  The first is that there is a bug in your
171 modified Pintos.  The second is that there is a bug in Bochs's
172 interface to @command{gdb} or in @command{gdb} itself.  The third is
173 that there is a bug in the original Pintos code.  The first and second
174 are quite likely, and you should seriously consider both.  We hope
175 that the third is less likely, but it is also possible.
176
177 @node Modifying Bochs
178 @section Modifying Bochs
179