Thursday, May 13, 2010

Embedded linux application remote debugging using GDB

As we all know, GDB is a pretty good debugging tool. Using it to debug applications running on the same Linux machine on which you run the GDB debugger is somewhat different from debugging an application running on a different architecture. This is called remote debugging, i.e, the application is running on a Linux base embedded system (with a different CPU), and the GDB debugger is running on the development host machine.

Starting from version 5.3 (am I right?), GDB supports remote debugging (even multi-threaded program).

Here is how to set up GDB for remote debugging. I'm using m68k as an example.(I know it's pretty old, but for other architecture, the process is pretty much the same).

1. Build and install GDB cross debugger
Download GDB from http://ftp.gnu.org/gnu/gdb, then make and install it.

tar zxvf gdb-6.6.tar.gz
cd gdb-6.6/
mkdir build
cd build/
../configure --program-prefix=m68k-uclinux- --target=m68k-elf --disable-werror
make
sudo make install

2. Build and install gdbserver. (Some linux distributions have gdbserver as an application in the rootfs. Some toolchains have it in the package. If it's not available there, you have to cross compile it)
gdbserver comes with the GDB package. So to cross compile it you can do:

$ cd gdb-6.6/gdb/gdbserver
$ export CC=m68k-ulinux-gcc // if required
$ export LD=m68k-ulinux-ld // if required
$ ./configure --host=m68k-uclinux --target=m68k-uclinux
$ make

3. Build the application with proper CFLAGS, LDFLAGS etc.
For CFLAGS, I believe you need at least -g. And if possible, give -O0 to disable optimization. An example of mytest.c will be:

m68l-uclinux-gcc -g -O0 -Wall -o mytest mytest.c

There are 2 executables generated, one is mytest stripped off symbols, and the other is mytest.gdb with all the symbols. It'll be used by the debugger to load symbol table.

4. Copy gdbserver and mytest over to target (using nfs for example)

5. On the target side, run application by gdbserver. I use network as the communication interface, but you can use serial port too.

gdbserver :3000 mytest

The 3000 is the port number on which gdbserver is listening for gdb commands.

6. On the client side, run cross debugger gdb, connect to gdbserver. And once connected, you can use any gdb commands for debugging.

m68k-uclinux-gdb 192.168.1.100:3000 ./mytest.gdb

192.168.1.100 as you imagine is the target's IP address. And if you want to be able to "list" source code in gdb, you have to put the source code (mytest.c) together with mytest.gdb in the same dir. (You can set it up if you really want to put the source code in other dirs by setting environment variables)

And that's it. There are some details I missed here, they can be found online or by gdb help.

No comments:

Post a Comment