Cross Arch Remote Debugging with GDB and gdbserver

To further debug a problem in my little initramfs system I recently added gdbserver to the build scripts. And since I have never done that before I might as well document how this works.

gdbserver which runs on the target basically just provides the ‘debugging backend’ and makes it available to a normal host gdb. This has the advantage that gdbserver is relatively easy to build for your embedded system of choice, it doesn’t provide a user interface and therefore doesn’t require readline/curses libraries.

So we cross compile gdbserver whose source can be found in the gdb tarball under gdb/gdbserver like this (replace $ARCH with your target architecture in my case it was armv4tl-unknown-linux-gnueabi):

cd gdb/gdbserver

./configure --build=`./config.guess` 
        --program-prefix="" &&
make &&
make DESTDIR=$SOMEDIR install

Then you will need a host gdb which understands the instructions of your target architecture. Your distribution probably only enabled support for your native architecture which means you will have to build your host gdb from source. Note that this time we only set --target and build from the top level directory.

./configure --host=`./config.guess` 
        --target=$ARCH &&
make &&
make DESTDIR=$SOMEDIR install

Now we can start our debugging session. On the target execute gdbserver and specify a port and your executable.

gdbserver :$SOME_PORT /path/to/file/you/want/to/debug

Back on the host connect to the listening gdbserver instance with your host gdb:

file /path/to/file/you/want/to/debug
target remote $IP_OF_TARGET:$SOME_PORT
set solib-absolute-prefix $ROOT_DIR

The solib-absolute-prefix should point to the root directory of the target on your host. Confused? Well you probably have cross compiled all your stuff for the target and installed it into a directory on your host and this is what I mean with “the root directory of the target on your host”. gdb will use the solib-absolute-prefix whenever it needs to load a shared library. What this means is that if the app you are debugging depends on a library gdb will load the library symbols from $ROOT_DIR/lib/ instead of /lib/ from the host system where it either has the wrong architecture or doesn’t exists at all.

Hope this is useful for someone out there. At the very least I now know where to look should I have to do it again in the future when I have already forgotten how it actually works.