交叉編譯 android 版本的gdb
交叉編譯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 還是在卡著,還沒有搞清原因,望高手給予指導啊。