Building GDB and GDBserver for cross debugging

1. Problem statement

"I have a ARM GNU/Linux board, and I want to be able to debug programs running in it, from the comfort of my x86_64 GNU/Linux machine. How do I build GDB and GDBserver for this scenario? I'm confused with the configure options I need to specify. Do I need to cross compile GDB for ARM too? Help!"

2. build, host, target, what??

As most GNU programs, GDB uses autoconf as part of its build system.

Here's the chapter of the GNU autoconf, automake and libtool book everyone building cross tools should read (do follow the right arrows):

Specifically, understanding the distinction between build, host and target is crucial.

 When using autoconf, there are three system definitions (or machine definitions)
 that are used to identify the “actors” in the build process; (...) These three definitions are:

host

    The system that is going to run the software once it is built. Once the software
    has been built, it will execute on this particular system.

build

    The system where the build process is being executed. For most uses this
    would be the same as the host system, but in case of cross-compilation
    the two obviously differ.

target

    The system against which the software being built will run on. This only exists, or rather
    has a meaning, when the software being built may interact specifically with a
    system that differs from the one it's being executed on (our host). This is the case
    for compilers, debuggers, profilers and analyzers and other tools in general.

Go on read those linked chapters please; I'll wait. :-) Alright, onwards.

When thinking in terms of "parked in front of a x86_64 machine", we say GDB runs on your host system, the x86_64 GNU/Linux machine, while GDBserver runs on the target, the ARM GNU/Linux board/machine.

However, GDB and GDBserver are separate programs. They get built separately, so we get to apply the build/host/target distinction for each separate build step.

3. Okay, how does that apply to GDB and GDBserver then?

3.1. For GDB

You need a GDB that runs on x86. With autoconf/configure, you use --host to specify where the program runs. So in your case that would be --host=x86_64-unknown-linux-gnu. However, if the program is meant to be run on the same system you are building from, then you don't need to specify that, as configure will pick your system as default for --host automatically. What you need is to make it so that the built GDB understands how to debug ARM GNU/Linux programs. This is where --target comes along. Say you have a arm-linux-gnueabi-gcc etc. cross toolchain available on your x86_64 development host, used for building programs that run on your ARM board (file names might vary, even for ARM GNU/Linux). From the compiler's file name, or from running arm-linux-gnueabi-gcc -v (look for the "Target:" line in the output), we see that gcc was configured with --target=arm-linux-gnueabi. We pass the same --target switch to GDB's configure. Done. That's it, really.

You'll see something like this:

$ /path/to/gdb-src/configure --target=arm-linux-gnueabi
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... arm-unknown-linux-gnueabi

If you don't specify --target, then the configure script defaults the target system to the same system you're building on. In this case, that would be x86_64-unknown-linux-gnu, which is not what we want.

Now run 'make all-gdb'. If you run just 'make', this will build all the top level components, including gdb, gdbserver, binutils, ld, gas, etc., all for the host. Alternatively, you can pass --disable-foo to configure to disable top level components, and then 'make' will build only the enabled ones. For example, '.../configure --disable-ld --disable-gas --disable-sim && make'.

To install, do 'make install-gdb', or 'make install' if you disabled components you don't want at configure time.

3.2. For GDBserver

So again, GDBserver runs on the "target" machine, the ARM GNU/Linux one. You could copy the sources over the the ARM GNU/Linux machine, and build it there. The standard /path/to/gdb-src/configure && make && make install will work fine.

However, you want to build GDBserver in the comfort of your x86_64 GNU/Linux host. You have an ARM cross compiler handy after all, right? Recapping from autoconf's build/host/target distinction, --host is used to specify where the program runs. Bingo! Since GDBserver will run on ARM, you pass --host=arm-linux-gnueabi to configure. You'll get something like:

$ /path/to/gdb-src/configure --host=arm-linux-gnueabi
checking build system type... x86_64-unknown-linux-gnu
checking host system type... arm-unknown-linux-gnueabi
checking target system type... arm-unknown-linux-gnueabi

("But why not --target?" Okay, you need to go read the build/host/target distinction again. ;-) --target doesn't really make sense for GDBserver, because it not a "cross" tool -- it knows how to debug the programs on its own system. It's no different from most other programs running on the ARM system, like grep, sed, etc, so you cross build it just like all other autoconf/configure programs.)

Note, you run the same toplevel configure for GDBserver as you did for GDB (/path/to/gdb-src/configure). Now do 'make all-gdbserver'. (In GDB/GDBserver versions prior to 10.1, GDBserver was not a top level component, and you would need to run GDBserver's configure instead (/path/to/gdb-src/gdb/gdbserver/configure), and do 'make'.)

Same as when building GDB, you can pass --disable-foo to disable top level components, you don't need on your target machine, including GDB, and then you can just use 'make'. For example, '.../configure --disable-gdb --disable-ld --disable-gas --disable-sim --disable-gprofng && make'.

To install, do 'make install-gdbserver', or 'make install' if you disabled components you don't want at configure time.

4. Troubleshooting

4.1. make uses system compiler?

If you've configured with --host=$host, but make uses the system's gcc instead of $host-gcc, make sure the latter can be found in your PATH, and that you can execute it (e.g., try $ arm-unknown-linux-gnueabi-gcc -v), and start over. The reason is that if configure doesn't find a usable $host-gcc, then it falls back to "gcc". See here for more info.

5. On separate build dirs

Final note: You don't have to, but I recommend building on a separate build directory from the sources. Like,

This way, at any time you want to do a build from scratch, you just need to wipe (rm -rf) the build directories.

6. TL;DR

It's not that long! Learning this stuff properly will translate into cross building all sorts of GNU autoconf based programs and libraries, so it's a skill worth having.

Anyway, to recap:

For GDB, do 'configure --target=arm-linux-gnueabi'. Run the toplevel configure for that (/path/to/gdb-src/configure). Do 'make all-gdb' and 'make install-gdb'.

For GDBserver do 'configure --host=arm-linux-gnueabi'. Starting with GDB 10.1, run the toplevel configure for that (/path/to/gdb-src/configure). Do 'make all-gdbserver' and 'make install-gdbserver'. For older versions, run GDBserver's configure instead (/path/to/gdb-src/gdb/gdbserver/configure), and do 'make' and 'make install'.

None: BuildingCrossGDBandGDBserver (last edited 2022-04-18 15:35:56 by PedroAlves)

All content (C) 2008 Free Software Foundation. For terms of use, redistribution, and modification, please see the WikiLicense page.