GDB 跨平台交叉编译

1. 环境配置

1.1 源码来源

在如下链接下载gdb源码:https://ftp.gnu.org/gnu/gdb/

1.2 源码解压

通过如下指令解压源码

tar -xf gdb-14.1.tar.xz

1.3 configure

先执行configure以便配置编译环境,如下所示:

cd gdb-14.1/
 ./configure --enable-mpers=no --host=aarch64-linux-gnu --target=aarch64-linux-gnu CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld --prefix=xxx/gdb-14.1/

1.3.1 configure报错

在执行上述configure指令后,报了如下错误,应该是GMP和 MPFR版本过低导致:

checking build system type... x86_64-pc-linux-gnu
...
checking for aarch64-linux-gnu-gdc... no
checking for gdc... no
checking whether the D compiler works... no
checking how to compare bootstrapped objects... cmp --ignore-initial=16 $$f1 $$f2
checking for objdir... .libs
checking for the correct version of gmp.h... no
configure: error: Building GDB requires GMP 4.2+, and MPFR 3.1.0+.        《《《 报错
Try the --with-gmp and/or --with-mpfr options to specify
their locations.  If you obtained GMP and/or MPFR from a vendor
distribution package, make sure that you have installed both the libraries
and the header files.  They may be located in separate packages.

可参考如下博文中的解决方法,拉取最新的GMP和 MPFR进行本地编译(同样需要交叉编译):

https://blog.csdn.net/qq_36393978/article/details/118678521

编译gmp

源码:https://ftp.gnu.org/gnu/gmp/

解压编译:

tar -xf gmp-6.3.0.tar.xz
cd gmp-6.3.0/
./configure --enable-mpers=no --host=aarch64-linux-gnu --target=aarch64-linux-gnu CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld --prefix=xxx/gmp-6.3.0
make
sudo make install

编译mpfr

源码https://ftp.gnu.org/gnu/mpfr/

解压编译

tar -xf mpfr-4.2.1.tar.xz
cd mpfr-4.2.1/
./configure --with-gmp=/usr/local/gmp-6.3.0 --host=aarch64-linux-gnu --target=aarch64-linux-gnu CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld --prefix=xxx/mpfr-4.2.1
make
sudo make install

编译mpc

源码获取

https://ftp.gnu.org/gnu/mpc/

解压编译

tar -xf mpc-1.3.1.tar.gz
cd mpc-1.3.1/
./configure --with-gmp=/usr/local/gmp-6.3.0 --with-mpfr=/usr/local/mpfr-4.2.1 --host=aarch64-linux-gnu --target=aarch64-linux-gnu CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld --prefix=xxx/mpc-1.3.1
make
sudo make install

编译安装完上述依赖库后,按如下指令重新执行gdb的configure指令,此过程未再报错。

./configure --with-mpfr=/usr/local/mpfr-4.2.1 --with-gmp=/usr/local/gmp-6.3.0 --with-mpc=/usr/local/mpc-1.3.1 --host=aarch64-linux-gnu --target=aarch64-linux-gnu CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld AR=${CROSS_COMPILE}ar --prefix=xxx/gdb-14.1/

2. 编译

直接执行make指令进行编译。

2.1 编译报错

linux-aarch64-low.cc:216:16: note: forward declaration of ‘struct aarch64_store_gregset(regcache*, const void*)::user_pt_regs’
  216 |   const struct user_pt_regs *regset = (const struct user_pt_regs *) buf;
      |                ^~~~~~~~~~~~
...
./../gdb/nat/aarch64-scalable-linux-sigcontext.h:275:28: note: in expansion of macro ‘SVE_PT_FPSIMD_SIZE’
  275 |   : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
      |                            ^~~~~~~~~~~~~~~~~~
linux-aarch64-low.cc:925:21: note: in expansion of macro ‘SVE_PT_SIZE’
  925 |      regset->size = SVE_PT_SIZE (AARCH64_MAX_SVE_VQ, SVE_PT_REGS_SVE);
      |                     ^~~~~~~~~~~
make[2]: *** [Makefile:546: linux-aarch64-low.o] Error 1
make[1]: *** [Makefile:11607: all-gdbserver] Error 2
make: *** [Makefile:1021: all] Error 2

经分析,上述错误应该是**c++**编译导致,可加上如下configure选项解决:

CXX=${CROSS_COMPILE}g++

最终可用的配置如下:

./configure --with-mpfr=/usr/local/mpfr-4.2.1 --with-gmp=/usr/local/gmp-6.3.0 --with-mpc=/usr/local/mpc-1.3.1 --host=aarch64-linux-gnu --target=aarch64-linux-gnu CXX=${CROSS_COMPILE}g++ CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld AR=${CROSS_COMPILE}ar --prefix=xxx/gdb-14.1/

2.2 编译产物

解决完上述问题后,最终编译出可在样机中执行的gdbserver

2.3 gdbserver使用

2.3.1 样机端

  1. 将上述附件中的gdbserver_stripped tftp到样机的/bin目录下:
cd /bin;tftp -gr gdbserver 192.168.1.105;chmod +x gdbserver_stripped;
  1. 运行gdbserver:
gdbserver_stripped 192.168.1.105:1234 --attach `pgrep main`

2.3.2 主机端

  1. 运行toolchain的gdb:
aarch64-linux-gnu-gdb # 注意提前设置环境变量
  1. 远程连接样机:
set sysroot xxx
target remote 192.168.1.76:1234
  1. 样机串口打印如下信息说明gdbserver已成功连接:
Attached; pid = 1300
gdbserver: Unable to determine the number of hardware watchpoints available.
gdbserver: Unable to determine the number of hardware breakpoints available.
Listening on port 1234
Remote debugging from host 192.168.1.105, port 3465
  1. 在主机端的gdb中执行如下指令保存样机当前的core信息:
gcore ./core_dump.test  #或使用generate-core-file ./core_dump.test指令

执行上述指令后,可在当前路径下生成core文件core_dump.test,如下所示:

file core_dump.test
core_dump.test: ELF 64-bit LSB core file, ARM aarch64, version 1 (SYSV), SVR4-style, from '/bin/main'

接下来就可以使用gdb来分析上述core_dump.test了。