-
Notifications
You must be signed in to change notification settings - Fork 32
UsingGdbEffectively
GDB is the GNU Debugger. PnkFelix is using it to try to step through the code generated by Petit Larceny (and to try to make sense out of the bus errors he is getting).
There are better debuggers out there (PnkFelix definitely preferred working with the Green Hills debugger), but GDB is standard and it is free.
GDB Basics:
You can attach to a running process using the attach
command; this is one of the best ways I've found to debug an application that uses a REPL; attaching breakpoints the application immediately.
You set breakpoints with the b
command. In the general in Petit Larceny, you'll need to use the syntax where you pass the instruction's address directly, b *0xabcdef
, because many symbols are declared static
in the C code and thus GDB cannot distinquish one from another.
You resume after a breakpoint with the c
command.
You can print C expressions with the p
command.
Petit Larceny Debugging Patterns:
When you're trying to understand how a particular procedure is being invoked, you should compare it against some other procedure that actually does work.
Also, you may need to reenter the GDB debugger at various points, e.g. if you want to inspect the contents of memory directly. A reasonable way to do this is to set a breakpoint on a known procedure that is not called by the REPL. One such procedure is getprop
, which takes a symbol and an arbitrary second argument. Do (* 4 (procedure-ref getprop 0))
to figure out where the code for getprop
is located in memory. Lets assume that that returned 0x0a0efef
. Then attach GDB, and do b *0x0a0efef
. Then do c
to resume the REPL. Then when you make calls to getprop
, you'll hit the breakpoint, and you can mess around in the debugger. You can even print the second argument to getprop
(which can be an arbitrary object) by doing p {word[16]}(globals[5]-7)
GDB notes:
Using { ...
} instead of ( ... )
to do a cast will force GDB to do the cast, regardless of whether GDB thinks that the cast is valid or not (GDB will normally complain saying "invalid cast" when you try to do p (word[16])(globals[5]-7)
See also "Debugging with GDB": http://www.delorie.com/gnu/docs/gdb/gdb.html#SEC_Top