How to debug using GDB Server

_History:_ Another high traffic page from my previous site being

transitioned here.

---

If you've ever worked with embedded systems or built code for a system other than your build machine you've probably found that running code on native hardware can sometimes generate different results than on your [Beige Box][1]. Being able to run and debug your code on your target hardware can be very useful but sometimes quite difficult to do. Using GNU's Debugger [gdb][2] can be extremely cumbersome on its own and I typically prefer to use the GUI client [ddd][3]. With most of my projects, the target hardware does not have X support and most of my interactions are through Serial or Ethernet. If you are in the same situation you might find [gdbserver][4], which comes with gdb, of use.

For a while now I've been using building applications using a Cross Compiler Jail (see [blog post][5]) on my development system to make the use of cross compilers much simpler. I can compile inside a system that looks and feels like I'm on the target's OS having gcc, arch, and a bunch of other attributes all pointing to a ARM CPU even though I'm compiling on an x86\_64. No need for calling ``gcc-arm-unknown-linux-gnueabi-gcc`` when the jail macros it to ``gcc``.

Having this build environment is great. I can run the target binary before I even drop it on the board. But it still not the same when it comes to debugging. For this I need ``gdbserver``.

``gdbserver`` is an instance of ``gdb`` you run on your target hardware that allows all its hooks to connect to a desktop version. Since I'm working with two different architectures, I need to run ``gdb`` inside my jail to get all the hooks working correctly, which is no problem when using [Scratchbox][6]. But if you want to use ``ddd`` you run into the same lack of X support situation. ``ddd`` has a solution for that but theres a bit of a twist.

When starting ``ddd`` or ``gdb`` from the development system, the location of a copy of the libraries found on the target needs to be set before stepping through the code. To get these libraries to load do the following:

On the target, start ``gdbserver`` with your application. The IP Address is that of the development computer, not the target.

The next step is to start up ``ddd`` pointing it to your local debugger.

``/scratcbox/login`` should point to the location of your Scratchbox install's login script and ``./hello`` is the binary compiled for the target hardware on your build machine. ``ddd`` should now start up to the main section of your code.

Now we need to setup the Share Library Path. To do this go to the gdb console at the bottom of ``ddd``. See the notes at the bottom for more details.

Now set a breakpoint for your main function.

Continue your application till it hits your breakpoint. We can see if the shared libraries have loaded:

**Notes:** When setting the Shared Library Absolute Prefix you will need to point ``gdb`` to the location, on your host system, where the target's root file system is located. This should be the exact file system that is copied onto your target when flashing. When ``gdbserver`` starts the application to debug, it looks for the libraries on the target's file system. ``gdbserver`` then communications to ``gdb`` running on your host the path it uses to load these libraries (i.e. ``/lib/libstdc++.so.6``). By setting the Shared Library Absolute Prefix on your host system, the local running copy of ``gdb`` is able to attach the prefix to the location it receives from the target's ``gdbserver``. At that point ``gdb`` running on your host system is able to load the libraries allowing you to debug your code.

$ published: 2012-11-05 00:00 $

$ tags: #tutorial, #tools, #debug $

[1]

[2]

[3]

[4]

[5]

[6]

-- CC-BY-4.0 jecxjo 2012-11-05

Comments?

back