Debugging with GDB and POSE

Debugging with GDB and POSE

For PRC-Tools users (DevToolsPRCTools), the simplest way to do source-level debugging is to use the GCC debugger GDB and the Palm OS Emulator (POSE) (PalmOSEmulator).

The PRC-Tools linker generates a COFF-format file named the same as the PRC file, but without the .prc extension. In addition to the compiled object code, the COFF file contains the debugging symbols collected by the compiler when you use the -g switch. The build-prc post-link step strips this debugging information out when building the PRC-format executable.

For this example, let's say we're building a program called myprog.prc; the COFF version will be called myprog.

 

Preparing for Debugging

First you need to compile and link your program with the -g switch:

m68k-palmos-gcc -g -c myprog.c -o myprog.o ; m68k-palmos-gcc -g myprog.o -o myprog

You might leave the -g linker switch on all the time, as it only adds about 100 bytes to your program's executable. Compiling with -g does not affect the built PRC file at all ... as mentioned above, the debugging information collected by the compiler goes into the COFF executable, but isn't copied into the PRC file by build-prc. Therefore, you can leave the -g compiler switch on all the time without penalty.

A very useful compiler switch is -mdebug-labels. It will enable POSE to tell you e.g. which function allocated a memory region your app failed to free (AKA "memory leak"). This switch makes your app much bigger so you should only use it for debugging purposes.

 

Next, load the PRC file into POSE. Don't run it yet.

Now, load the COFF file up with the PRC-Tools version of GDB:

m68k-palmos-gdb myprog

 

Starting the Debugging Session

Now you need to tell GDB to hook up with POSE. Type this command on the GDB command line:

target pilot localhost:6414

This tells GDB to make a TCP connection to the copy of POSE running on this machine, listening on port 6414. (Yes, this means you could conceivably use GDB on a different machine from the one POSE is running on, by connecting over a network!) At this point, GDB has told POSE that it wants to debug your program, and it will wait patiently for POSE to set this up.

Now, start your program in POSE. POSE will do a few things to get your program started, and then pause your program and turn control over to GDB. Now you're free to set breakpoints, examine the state of the machine, do stepping and anything else you commonly can do with a debugger.

If your program is crashing the emulator or causing the debug ROM to display a "you shouldn't be doing that" message, it's easy to debug this with GDB. Set the debug session up as mentioned above, then run your program in POSE. When POSE halts and turns control over to GDB, simply type 'cont' (short for "continue") on the GDB command line to return control to POSE. POSE will break back to the debugger when you hit a bus error, an ErrFatalDisplayIf() call, a bad pointer dereference, or if you're running a debug ROM when your program does any number of other questionable things. GDB will be stopped at the offending line in your program. A useful command here is "bt", to get a call stack backtrace.

 

Intro to GDB

If your idea of a debugger is something integrated into a graphical IDE, GDB will come as a bit of a shock. It's an old-style command line debugger that nevertheless is quite powerful. There are a few commands you'll need to know to get started:

 

  • break PilotMain - Set a breakpoint. In this example, set a breakpoint on the PilotMain() function. There are many variations on the break command; say "help break" on the GDB command line to get more information. Or, read the online manual.
  • cont - When the program is paused, such as on a breakpoint, this will continue execution.
  • bt - Get a call stack backtrace.
  • step - Step forward one source line. This command "steps into" function calls.
  • next - Same as "step", but does not step into function calls.
  • print - Show the contents of a variable, or compute an expression. Like break, this is another very powerful command. See the docs.
  • help - Given alone on the command line, it tells you what you can get help on. You can then dig deeper into the help system with commands like "help break".
  • quit - Stop the debugged program, and leave GDB. This will also reset POSE, even if you weren't debugging your program.

This only scratches the surface. GDB, as I have said already, is a very powerful debugger. You would do well to read the manual.

 

Summary

To distill that longwinded exposition:

 

  1. Load the PRC version of your program into POSE
  2. Start up GDB with the COFF version of your program
  3. Tell GDB, "target pilot localhost:6414"
  4. Launch your program within POSE
  5. On the GDB command line, set up any breakpoints and such
  6. Tell GDB to "cont"inue running your program
  7. Debug on, dude...

Copyright © 2000-2001 by Warren Young. All rights reserved.

18 Feb 2003

Today: Sep 10, 2010