1. 程式人生 > >交叉編譯 android 版本的gdb

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