1. 程式人生 > >使用 GDB 除錯 Android 應用

使用 GDB 除錯 Android 應用

GNU 工程偵錯程式(GDB)是一個常用的 Unix 偵錯程式。本文詳述使用 gdb 除錯 Android 應用和程序的方法。

除錯執行中的應用或程序

gdbclient 是原始碼庫中的一個 shell 指令碼除錯工具,它位於 android-7.1.1_r22/development/scripts/gdbclient。該指令碼將根據 Android 原始碼庫的根目錄,設定埠轉發,在裝置上啟動適當的 gdbserver,在主機上啟動適當的 gdb,配置 gdb 查詢符號,並將 gdb 連線到遠端的 gdbserver

在執行 gdbclient 首先需要設定 ANDROID_BUILD_TOP

環境變數,這個環境變數可以手動設定,如:

/media/data/Androids/android-7.1.1_r22$ export ANDROID_BUILD_TOP=/media/data/Androids/android-7.1.1_r22

也可以通過如下命令設定:

/media/data/Androids/android-7.1.1_r22$ source build/envsetup.sh 
including device/asus/fugu/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator
-armv7-a-neon/vendorsetup.sh including device/generic/mini-emulator-mips64/vendorsetup.sh including device/generic/mini-emulator-mips/vendorsetup.sh including device/generic/mini-emulator-x86_64/vendorsetup.sh including device/generic/mini-emulator-x86/vendorsetup.sh including device/google/dragon/vendorsetup.sh including device/google/marlin/vendorsetup.
sh including device/htc/flounder/vendorsetup.sh including device/huawei/angler/vendorsetup.sh including device/lge/bullhead/vendorsetup.sh including device/linaro/hikey/vendorsetup.sh including device/moto/shamu/vendorsetup.sh including sdk/bash_completion/adb.bash [email protected]:/media/data/Androids/android-7.1.1_r22$ lunch 18 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=7.1.1 TARGET_PRODUCT=aosp_sailfish TARGET_BUILD_VARIANT=userdebug TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=arm64 TARGET_ARCH_VARIANT=armv8-a TARGET_CPU_VARIANT=generic TARGET_2ND_ARCH=arm TARGET_2ND_ARCH_VARIANT=armv7-a-neon TARGET_2ND_CPU_VARIANT=krait HOST_ARCH=x86_64 HOST_2ND_ARCH=x86 HOST_OS=linux HOST_OS_EXTRA=Linux-4.4.0-89-generic-x86_64-with-Ubuntu-16.04-xenial HOST_CROSS_OS=windows HOST_CROSS_ARCH=x86 HOST_CROSS_2ND_ARCH=x86_64 HOST_BUILD_TYPE=release BUILD_ID=NMF26X OUT_DIR=out ============================================

也就是 Android 原始碼庫編譯前配置。

如果沒有設定 ANDROID_BUILD_TOP 環境變數的話,在執行 gdbclient 時將報出如下的錯誤:

/media/data/Androids/android-7.1.1_r22$ development/scripts/gdbclient
$ANDROID_BUILD_TOP is not set. Source build/envsetup.sh.

有了前面的那些配置,即可使用 gdbclient 除錯 Android 應用程式了。要連線一個已經在執行的應用或本地層守護程序,則以 PID 作為引數執行 gdbclient。比如,要除錯 PID 為 1234 的程序,則執行:

$ gdbclient 1234

它會為我們準備一切。

除錯本地程序啟動

要除錯程序的啟動,則使用 gdbservergdbserver64 (64 位程序)。比如:

$ adb shell gdbserver64 :5039 /system/bin/screenrecord

示例輸出如下:

Process /system/bin/screenrecord created; pid = 12571
Listening on port 5039

接著,從 gdbserver 的輸出中得到應用程式的 PID,並在另一個終端視窗中使用如下命令:

$ gdbclient 12571

最後,在 gdb 提示符下鍵入 continue

使用的 gdbserver 與實際執行的應用程式格式不匹配時,在執行 gdbclient 時將報出如下的錯誤:

$ gdbclient 12484
including device/asus/fugu/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips64/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/google/dragon/vendorsetup.sh
including device/google/marlin/vendorsetup.sh
including device/htc/flounder/vendorsetup.sh
including device/huawei/angler/vendorsetup.sh
including device/lge/bullhead/vendorsetup.sh
including device/linaro/hikey/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including sdk/bash_completion/adb.bash

It looks like gdbserver is already attached to 12484 (process is traced), trying to connect to it using local port=5039
GNU gdb (GDB) 7.11
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from out/target/product/sailfish/symbols/system/bin/screenrecord...done.
warning: Selected architecture aarch64 is not compatible with reported target architecture arm
out/target/product/sailfish/gdbclient.cmds:4: Error in sourced command file:
Reply contains invalid hex digit 59
(gdb) break main
Breakpoint 1 at 0x5820: file frameworks/av/cmds/screenrecord/screenrecord.cpp, line 900.
(gdb) r
Starting program: /media/data/Androids/android-7.1.1_r22/out/target/product/sailfish/symbols/system/bin/screenrecord 
/usr/local/google/buildbot/src/android/master-ndk/toolchain/gdb/gdb-7.11/gdb/regcache.c:1056: internal-error: regcache_raw_supply: Assertion `regnum >= 0 && regnum < regcache->descr->nr_raw_registers' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) y

This is a bug, please report it.  For instructions, see:
<http://www.gnu.org/software/gdb/bugs/>.

/usr/local/google/buildbot/src/android/master-ndk/toolchain/gdb/gdb-7.11/gdb/regcache.c:1056: internal-error: regcache_raw_supply: Assertion `regnum >= 0 && regnum < regcache->descr->nr_raw_registers' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) y
/media/data/Androids/android-7.1.1_r22/prebuilts/gdb/linux-x86/bin/gdb: 行 3: 12882 已放棄               (核心已轉儲) PYTHONHOME="$GDBDIR/.." "$GDBDIR/gdb-orig" "[email protected]"
[email protected]:/media/data/Androids/android-7.1.1_r22$ /bin/bash: /media/data/Androids/android-7.1.1_r22/out/target/product/sailfish/symbols/system/bin/screenrecord: cannot execute binary file: 可執行檔案格式錯誤
/bin/bash: /media/data/Androids/android-7.1.1_r22/out/target/product/sailfish/symbols/system/bin/screenrecord: 成功

即我們在 gdb 的提示符下輸入 continue 執行應用程式之後,報出了 可執行檔案格式錯誤

Done.