交叉编译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 还是在卡着,还没有搞清原因,望高手给予指导啊。