交叉编译 android 版本的gdb

本文详细介绍如何使用Android NDK r12b交叉编译GDB 7.11版本的过程,包括环境搭建、编译步骤及解决常见编译错误的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

交叉编译gdb,在网上已经烂大街,但资料都比较散,在此总结一下我在编译期间遇到的所有问题:

NDK版本:android-ndk-r12b

gdb 版本:http://ftp.gnu.org/gnu/gdb/gdb-7.11.tar.xz

系统版本:ubuntu  16.04  14.04


一、搭建环境:

1、下载NDK,生成交叉编译工具链

$NDK/build/tools/make-standalone-toolchain.sh  --platform=android-23  --arch=arm64   --ndk-dir=/home/chengli/SoftWare/NDK/android-ndk-r12b  --install-dir=/home/name/SoftWare/NDK/android-ndk-r12b/tmp/toolchain

2、搭建64位交叉编译环境

export PATH=/home/name/SoftWare/NDK/android-ndk-r12b/tmp/toolchain/bin:$PATH

export CC="aarch64-linux-android-gcc  -pie -fPIE  --sysroot=/home/chengli/SoftWare/NDK/android-ndk-r12b/tmp/toolchain/sysroot"

export CXX="aarch64-linux-android-g++ -pie -fPIE   --sysroot=/home/chengli/SoftWare/NDK/android-ndk-r12b/tmp/toolchain/sysroot"

export CXXFLAGS="-lstdc++"

备注:可以将 环境搭建 作为一个方法写入bashrc中。

添加 pie 的原因:android 在新版本上开启了PIE这个安全机制,如果不添加此参数,

编译后放到手机中运行报错:

error: only position independent executables (PIE) are supported.

在mk 中修改为:

LOCAL_CFLAGS += -pie -fPIE

LOCAL_LDFLAGS += -pie -fPIE


二、生成android 版本gdb

./configure  --host=aarch64-linux-android  --target=aarch64-linux-android  --prefix=/home/name/SoftWare/gdb/out

make

make install


三、遇到的问题:

1、

localealias.c:33:24: fatal error: stdio_ext.h: No such file or directory
 # include <stdio_ext.h>
                        ^
compilation terminated.

缺少.h文件,将android 6.0中的./bionic/libc/include/stdio_ext.h, cp到  交叉变异环境中。

cp android6.0/bionic/libc/include/stdio_ext.h  ~/software/android-ndk-r12b/tmp/toolchain/sysroot/usr/include/



2、

unknown type name 'sim_cpu' ......

在sim/aarch64/cpustate.h文件中倒入头文件

#include "sim-base.h"



3、报错

arm-linux-nat.c:92:19: error: 'PT_GETFPREGS' undeclared (first use in this function)
     ret = ptrace (PT_GETFPREGS, tid, 0, fp);
                   

修改 交叉编译环境中的ptrace.h文件,加入以下几行(应该只需要加对应行,但以防万一全加):

/* glibc exports a different set of PT_ names too... */
#define PT_TRACE_ME PTRACE_TRACEME
#define PT_READ_I PTRACE_PEEKTEXT
#define PT_READ_D PTRACE_PEEKDATA
#define PT_READ_U PTRACE_PEEKUSR
#define PT_WRITE_I PTRACE_POKETEXT
#define PT_WRITE_D PTRACE_POKEDATA
#define PT_WRITE_U PTRACE_POKEUSR
#define PT_CONT PTRACE_CONT
#define PT_KILL PTRACE_KILL
#define PT_STEP PTRACE_SINGLESTEP
#define PT_GETFPREGS PTRACE_GETFPREGS
#define PT_ATTACH PTRACE_ATTACH
#define PT_DETACH PTRACE_DETACH
#define PT_SYSCALL PTRACE_SYSCALL
#define PT_SETOPTIONS PTRACE_SETOPTIONS
#define PT_GETEVENTMSG PTRACE_GETEVENTMSG
#define PT_GETSIGINFO PTRACE_GETSIGINFO
#define PT_SETSIGINFO PTRACE_SETSIGINFO




4、

-MF .deps/linux-thread-db.Tpo linux-thread-db.c
linux-thread-db.c: In function 'thread_from_lwp':
linux-thread-db.c:344:5: error: 'td_thrhandle_t' has no member named 'th_unique'
   th.th_unique = 0;
     ^
Makefile:1136: recipe for target 'linux-thread-db.o' failed
make[2]: *** [linux-thread-db.o] Error 1

注销 linux-thread-db.c 中的对应行


5、

   ../readline/libreadline.a ../opcodes/libopcodes.a ../bfd/libbfd.a -L./../zlib -lz ./../intl/libintl.a ../libiberty/libiberty.a ../libdecnumber/libdecnumber.a    -lm     ../libiberty/libiberty.a  build-gnulib/import/libgnu.a  -ldl -Wl,--dynamic-list=./proc-service.list

complete.c:2059: error: undefined reference to 'setpwent'
collect2: error: ld returned 1 exit status


修改complete.c 对应行

改为:

    #if defined (HAVE_GETPWENT)       
       setpwent ();
    #endif


6、错误:

linux-low.c:115:3: error: conflicting types for 'Elf32_auxv_t'
 } Elf32_auxv_t;
   ^
In file included from linux-low.c:55:0:
/home/chengli/SoftWare/NDK/test/android-ndk-r12b/tmp/toolchain/sysroot/usr/include/elf.h:42:3: note: previous declaration of 'Elf32_auxv_t' was here
 } Elf32_auxv_t;
   ^
linux-low.c:130:3: error: conflicting types for 'Elf64_auxv_t'
 } Elf64_auxv_t;
   ^
In file included from linux-low.c:55:0:
/home/chengli/SoftWare/NDK/test/android-ndk-r12b/tmp/toolchain/sysroot/usr/include/elf.h:49:3: note: previous declaration of 'Elf64_auxv_t' was here
 } Elf64_auxv_t;


修改 交叉编译环境中的android-ndk-r12b/tmp/toolchain/sysroot/usr/include/elf.h 文件,将冲突名,改为其他名称

当然你也可以将 gdb 源码包中的所有名改了。


7、

./common/sim-events.h:94:3: error: unknown type name 'SIM_ELAPSED_TIME'
   SIM_ELAPSED_TIME resume_wallclock;
   ^
Makefile:514: recipe for target 'sim-arange.o' failed
make[3]: *** [sim-arange.o] Error 1

将sim-utils.h 在sim-events.h 内导入,或者将报错句改为

unsigned long  resume_wallclock;



8、

tracepoint-ipa.o: In function `get_timestamp':
/home/chengli/SoftWare/gdb/tmp/gdb-7.11/gdb/gdbserver/tracepoint.c:7349: undefined reference to `rpl_gettimeofday'

将 这一行,添加到报错行之前。

#undef gettimeofday



9、

/home/hecheng/software/gdb/gdb-7.11/missing: 81: /home/hecheng/software/gdb/gdb-7.11/missing: makeinfo: not found

安装makeinfo命令。


到此一个arm64 的gdb 就生成了,可以将其push 进手机中,在adb 中,直接gdb 调试进程。

备注:

1、正常gdb 较大,可以使用aarch64-linux-android-strip 对编译出来的gdb,进行裁剪,以缩小体积。

       2、本次编译出来的gdb,attach 到 进程上,进程就变为T 状态了,continue 执行后,进程状态变为S了但是 实际上apk 还是在卡着,还没有搞清原因,望高手给予指导啊。


加壳应用反编译




<think>好的,用户的问题是询问交叉编译工具链是否包含GDB调试工具。我需要结合用户提供的引用内容和之前的问题来给出准确的回答。 首先,用户引用了多个资料,其中引用1提到交叉编译工具链中的GDB分为arm-pc-gdb、arm-gdb和arm-gdbserver。这说明在交叉编译环境下,GDB可能分为不同版本,比如在主机上运行的交叉编译版本和目标机上的gdbserver。 引用2提到制作交叉编译工具链时,GDB需要单独配置,因为嵌入式平台的工具链制作方法与普通不同,硬件可能无法直接运行常规编译的工具。这说明交叉编译工具链中的GDB可能需要特别处理,不一定默认包含。 引用3和4详细描述了交叉编译工具链的制作过程,包括下载源码、编译binutils、gcc、glibc等步骤。这里没有明确提到GDB是否包含在内,但通常标准工具链可能不包含调试工具,需要额外配置。 引用5提到交叉编译的步骤,如预处理、编译、汇编和链接,但没有直接涉及调试工具。但用户之前的回答中详细说明了如何在Buildroot中启用GDB,包括在菜单中配置选项,这说明交叉工具链可能需要手动选择包含GDB组件。 用户之前的问题是关于配置GDB调试段错误,其中提到在Buildroot中启用GDB需要手动勾选相关选项,如Toolchain中的Build cross gdb和Target packages中的gdb。这说明交叉编译工具链默认可能不包含GDB,需要用户主动配置。 综合这些信息,交叉编译工具链是否包含GDB取决于具体的构建配置。通常,标准工具链可能不包含,但通过配置(如使用Buildroot或手动编译)可以包含交叉编译GDBgdbserver。需要向用户说明这一点,并区分主机端和目标端的工具,同时给出验证方法和常见场景。</think>根据交叉编译工具链的构建方式和目标平台需求,**GDB调试工具可能包含在工具链中**,但需要明确区分以下两个组成部分: --- ### 一、交叉编译工具链中GDB的组成 1. **主机端工具(Host-side)** - **交叉编译GDB** (例如 `aarch64-linux-gnu-gdb`) 用于在开发机(x86主机)上调试目标平台(如ARM设备)的程序,需要 **显式配置并编译到工具链中**。 > *引用[1]中提到的 `arm-pc-gdb` 即为此类工具* 2. **目标端工具(Target-side)** - **gdbserver** (例如 `/usr/bin/gdbserver`) 需在目标设备(嵌入式平台)上运行,用于与主机端GDB通信,通常需要 **单独安装或编译到根文件系统中**[^1][^2]。 --- ### 二、是否默认包含GDB? #### 1. **标准交叉编译工具链(如Linaro、Buildroot默认配置)** - ❌ **不包含GDB** 默认仅提供编译器(gcc)、链接器(ld)等基础工具,调试工具需手动启用。 > *引用[2]指出嵌入式平台工具链需按特定方法制作,不会默认包含调试工具* #### 2. **自定义配置的交叉编译工具链** - ✅ **可包含GDB** 在构建工具链时需 **显式启用GDB组件**: ```bash # 例如Buildroot配置 make menuconfig → Toolchain → Build cross gdb for the host # 启用主机端GDB → Target packages → Debugging → gdb # 启用目标端gdbserver ``` > *引用[3]中提到的工具链制作流程可扩展包含GDB* --- ### 三、验证方法 #### 1. 检查工具链目录结构 ```bash # 查看是否包含交叉编译GDB ls ${CROSS_COMPILE_PATH}/bin | grep -E "aarch64-linux-gnu-gdb|arm-linux-gnueabihf-gdb" # 检查目标端gdbserver是否存在 ls ${SYSROOT_PATH}/usr/bin | grep gdbserver ``` #### 2. 测试调试功能 主机端调试: ```bash aarch64-linux-gnu-gdb -ex "target remote 192.168.1.100:1234" ./test_program ``` 目标端执行: ```bash gdbserver :1234 ./test_program # 目标设备需支持gdbserver ``` --- ### 四、常见场景 1. **Android NDK工具链** - 使用 `make-standalone-toolchain.sh` 生成工具链时,默认 **不包含GDB**,需手动添加 `--include-debug` 参数[^4]。 2. **Buildroot/Yocto定制系统** - 需通过菜单配置明确勾选GDB组件,否则生成的根文件系统中 **无gdbserver**。 --- ### 总结 | 工具链类型 | 主机端GDB | 目标端gdbserver | |------------------|-----------|-----------------| | 标准预编译工具链 | ❌ | ❌ | | 自定义配置工具链 | ✅(可选) | ✅(可选) | [^1]: 交叉编译GDB调试工具链的组成与功能 [^2]: 嵌入式系统调试工具链的构建方法 [^3]: Linux交叉编译工具链制作流程 --- ### 相关问题 1. 如何在Buildroot中同时启用主机端GDB和目标端gdbserver? 2. Android NDK工具链如何集成GDB调试功能? 3. 交叉编译gdbserver运行时报错“缺少动态链接库”如何解决?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值