使用 GDB 除錯 Android 應用
阿新 • • 發佈:2018-12-29
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
它會為我們準備一切。
除錯本地程序啟動
要除錯程序的啟動,則使用 gdbserver
或 gdbserver64
(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.