Note: this page is incomplete and not totally tested yet. The remote debugging section works fine, but I haven't tried the native version yet - remote debugging is better anyway!
These days, using firmware 2.0, you can fairly easily set things up so your PC can communicate with your GP2X via the USB cable, using ordinary network protocols. This is documented elsewhere in the wiki see: Tcp/ip_over_usb
Presumably you already have a working toolchain, and presumably you're linking statically. If you're using the old GPH-provided compiler, get rid of it quick before it's too late. If you're dynamic-linking with a more recent compiler then you've already overcome plenty of issues - you'll also have to work a bit harder to get gdb working, as it won't be able to find the right dynamic libraries out of the box. See .
You'll need a working copy of gdb and possibly gdbserver, depending how you go - see Obtaining GDB for help with this.
Hosts and targets
Something that comes up when you're building toolchains is a lot of confusion about hosts and targets. As far as the GNU tools are concerned, the host is the machine the tool binary it's going to create runs on, and the target is the machine whose binary format the tool understands/generates. The version of gcc you're using to build for the GP2X is probably targetted at an arm-linux architecture, but it's probably hosted on an Intel PC.
In this page we're going to consider a few different ways to build gdb. We'll always be targetting the GP2X, i.e. the gdb we build is meant to debug GP2X executables, but we'll be hosting on different platforms.
Debugging information in executables
If you want to debug your executable, you kind of need to leave plenty of debugging information in. As this bloats it, most people strip it out using the "-s" option to the linker - don't do this! For extra debugging information, use the "-g" switch to the compiler - do this, it's good.
If you're using the first method below then you're stuck with uploading a bigger executable to your GP2X. If you're using the second method, you can strip the executable before sending it, but keep a version with debugging information on your PC. They have to be in sync! To generate a stripped version, use arm-linux-strip or whatever came with your toolchain. Use the "-o" option to output a stripped copy with a different name, otherwise it strips the executable in-place, which you don't want. This postprocess stripping has exactly the same effect as the "-s" option to the linker.
e.g. my makefile looks like this:
$(PROG): $(OBJ) $(CC) -o $@-debug $^ `$(ALLEGRO_CONFIG) --libs release` -static $(STRIP) $@-debug -o $@
where CC and STRIP are arm-open2x-linux-gcc and arm-open2x-linux-strip respectively. This creates a debugging executable with "-debug" on the end of its name, and a stripped one without.
Running gdb on the target
This is one way to debug, and perhaps the simplest to set up, but it's somewhat uncomfortable and there's no prospect for integration with PC-side tools like IDEs.
You'll need a copy of gdb compiled to run on the GP2X. See Obtaining GDB for more details.
The easiest way to run this is by telnetting into your GP2X over the network interface. At the bash prompt, kill the menu:
and change to the directory of the program you want to debug:
Normally at this point you'd run your program, but to debug it, instead run gdb and pass your program as a command line argument:
After this command, gdb will start and your program will be loaded, but not executed. To begin execution, issue the "run" command. See the official GDB documentation  for other commands or type help in gdb.
Running gdbserver on the GP2X and gdb on your PC
The gdb package supports remote debugging - that is, running gdb on your PC and having it communicate with the target by other means. This is more powerful - it places less load on the poor GP2X, enables you to perform most operations directly on your PC, and most importantly, major IDEs know how to connect to the remote gdbserver, so you can debug in a more comfortable environment, if you like that kind of thing.
In this case, we need gdb configured to run on the PC, but still target the GP2X, and we need a separate server program to handle the GP2X side of things - running on the GP2X, also targetting the GP2X. Again, see Obtaining GDB for further information on obtaining these programs.
The actual usage is similar to local debugging (as above), but this time you're running your app via gdbserver, not gdb, and you need to provide it with a port number to bind to:
/mnt/sd/gdb/gdbserver foo:1234 myprogram
This runs the server, binding to port 1234 (ignore the "foo" bit), and loads your program. Next, you run gdb on your PC and tell it the program you're going to debug. Note that I'm using the copy of the program with debug info in it.
Then connect it to the target:
target remote 192.168.0.2:1234
Note the port number, which should match the number given to gdbserver. The IP address may also vary - 192.168.0.2 is the default for the GP2X but you may have changed it. Finally, you can issue the "continue" command to start your program, as above.