一、前言
我們在Linux-x86_64、Linux-aarch64等環(huán)境下可以通過編譯對應的gdb工具直接在宿主機上面進行gdb調(diào)試,非常方便。但是我們發(fā)現(xiàn)在android上面進行gdb調(diào)試的話,只能通過系統(tǒng)自帶的gdbserver和ndk自帶的host主機(一般都是window、Linux)上的gdb進行網(wǎng)絡調(diào)試,非常的不方便。
對于這種需求,我們是否可以像Linux-aarch64一樣利用交叉編譯出android環(huán)境的gdb工具,顯然是可以的。
二、準備環(huán)境
1.官方下載gdb源碼:https://sourceware.org/pub/gdb/releases/?C=M;O=D
這里我選擇的是gdb-8.0.tar.gz
2.NDK環(huán)境準備
這里我下載的是NDK-r18b, 下載地址:Unsupported Downloads · android/ndk Wiki · GitHub
重點說明下: gdb版本和ndk版本最好能匹配上,否則編譯過程中遇到各種不同的編譯報錯問題(猜測是高版本的需要編譯器支持)。上面是我通過無數(shù)次實驗得到的可以編譯通過版本。
3.構建android工具鏈
通過以下命令進行編譯生成
export ANDROID_NDK="/opt/android-ndk-r18b"
//32位
sh ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-21 --install-dir=$HOME/android-toolchain_32 --toolchain=arm-linux-androideabi-4.9
//64位
sh ${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh --arch=aarch64 --platform=android-21 --install-dir=$HOME/android-toolchain_64 --toolchain=aarch64-linux-android-4.9
三、編譯
1.解壓gdb-8.0.tar.gz
tar -xvf gdb-8.0.tar.gz
2.進入gdb-8.0目錄,配置編譯腳本,如下
//64位,build_android64.sh
./configure --host=aarch64-linux-android --target=aarch64-linux-android CC=aarch64-linux-android-gcc CXX=aarch64-linux-android-g++ --prefix=/home/yw/opensource/gdb-8.0/android64
make -j4
make install
//32位,build_android32.sh
./configure --host=arm-linux-androideabi --target=arm-linux-androideabi CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ --prefix=/home/yw/opensource/gdb-8.0/android32
make -j4
make install
以上腳本最后是兩個單獨的sh腳本,單獨編譯出來。記得編譯前make clean掉上次的緩存。及config.cache清理:
find . -name "config.cache" | xargs rm -f
3.環(huán)境變量配置
在用戶目錄下.bash_profile中添加工具鏈path:
export PATH=$PATH:/opt/android-ndk-r18b:/home/yw/android-toolchain_64/bin:/home/yw/android-toolchain_32/bin
然后執(zhí)行source .bash_profile命令激活,或者在當前終端直接執(zhí)行export都可以。
4.執(zhí)行編譯
sh build_android64.sh
以上為64位編譯腳本,32位同理。程序生成在對應指定的目錄下。
四、gdb調(diào)試使用
通過adb push gdb到android設備上。運行可能需要libc++_shared.so,在將NDK中的庫上傳到android設備上

現(xiàn)在就開始愉快使用gdb工具啦!

5.編譯過程可能遇到的問題及解決方法
1.類型沖突 Elf32_auxv_t Elf64_auxv_t
linux-low.c:116:3: error: typedef redefinition with different types (‘struct Elf32_auxv_t’ vs ‘struct Elf32_auxv_t’)
linux-low.c:131:3: error: typedef redefinition with different types (‘struct Elf64_auxv_t’ vs ‘struct Elf64_auxv_t’)
這個在ndk的elf.h 中已經(jīng)有定義,直接注釋掉gdb/gdbserver/linux-low.c 中的定義
2. setpwent 沒定義
complete.c:2060: error: undefined reference to ‘setpwent’
readline/complete.c 中假如宏判斷包含
#if defined(HAVE_GETPWENT)
setpwent ();
#endif
運行段錯誤
手動加打印 發(fā)現(xiàn)在signals-state-save-restore.c --> save_original_signals_state 掛掉,
直接注釋掉internal_error這行,如下:

參考鏈接:https://blog.csdn.net/shumanzhou/article/details/119148514