Cross Arch Remote Debugging with gdb and gdbserver

11.10.2009 at 23:31

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` 
        --target=$ARCH 
        --host=$ARCH 
        --prefix=/usr 
        --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 toplevel directory.

./configure --host=`./config.guess` 
        --build=`./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:

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

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/libfoo.so instead of /lib/libfoo.so 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.

Marc

Comments (5)

Very useful

13.02.2011 by Pablo

Just what I needed today after wading through tons of other info. Thanks for posting this!

Very helpfuld

23.04.2012 by Dan D

Thanks, Marc. This guide helped me get gdb setup for an x86 host and an ARM target. Mucho gracias!

How to get the proper architecture

31.05.2012 by vv

Hi How did u get the proper architecture name to feed as arg? I get erros like x86_64-pc-none from bfd/config.bfd for one of the most basic architectures.

Thanks!

18.09.2013 by Samuel

It worked! I have tried this multiple times in the past (I think even using this how-to), but I've always given up because I ran in to problems. This time for some reason it worked. I got some messages the looked like errors, e.g.: (gdb) target remote 192.168.50.148:2345 Remote debugging using 192.168.50.1482345 warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. 0x44ab8c80 in ?? () However, when I continued with "set solib-absolute-prefix ...", "b main", and "continue" I hit the breakpoint in main() and could debug as normal. Thanks!

Thanks

20.12.2016 by Alexander (bashmachnikov[at]gmail[dot]com)

It was very helpful in my case. Thanks.

1