GDB远程调试Android上的可执行ELF文件
@(Android研究)[android|gdb]
[TOC]
文章背景
现在需要将Linux上的工具移植到Android上,通常Linux上代码是通过Makefile管理编译选项,为了直接使用Makefile而不使用Android.mk文件,则需要使用Android NDK的编译工具链进行交叉编译,成功时会输出一个可在Android上运行的ELF可执行文件,在本文中假设这个ELF可执行文件名为"android-exe"。本文介绍如何在本机(本文中的本机系统是Linux)上通过GDB远程调试Android上的"android-exe"。
为何使用GDB调试
- Android NDK提供了一个ndk-gdb的脚本,该脚本只能调试通过Android.mk编译的本地代码。详情可参考:ndk-gdb。
- 没有找到Android Studio或eclipse远程调试Android ELF可执行文件的方法。
前置说明
我的Android NDK的版本:android-ndk-r11b。
- 将Android设备上"/system/lib"目录下的所有文件通过adb pull全部拉取到本机上。给本机上保存这些文件的目录取一个别名:$SYSTEM_LIB。
- 将Android设备上"/system/bin"目录下的所有文件通过adb pull全部拉取到本机上。给本机上保存这些文件的目录取一个别名:$SYSTEM_BIN。(目前只有/system/bin/linker这个文件有用)
- 设,Android NDK工具链编译代码时所选取的Android平台为android-21,那么该平台库对应的目录是:$NDK/platforms/android-21/arch-arm/usr/lib/,给该目录取一个别名:$PLATFORMS_21_LIB。
- Android NDK的gdb路径:$NDK/prebuilt/linux-x86_64/bin/gdb。
- 我使用的是CyanogenMod的Android ROM,该ROM中自带gdbserver。
- 设,"android-exe"在Android上的完整路径是"/data/local/tmp/android-exe"。
步骤1、2是为了本机GDB远程调试时可以找到Android系统库的符号。
调试
1. 启动gdb server
在adb shell中进入"/data/local/tmp/"目录,然后执行下面的命令:
gdbserver :1234 android-exe
1234表示gdb监听的调试端口,android-exe是被调试的ELF可执行程序。
如果调试的程序需要传入参数,那么输入命令:gdbserver :1234 android-exe [参数...]
2. 重定向端口
在本机上输入下面的命令重定向端口:
adb forward tcp:1234 tcp:1234
3. GDB调试
输入下面的命令进行调试
$NDK/prebuilt/linux-x86_64/bin/gdb android-exe
这里的"android-exe"是指本机上android-exe的存储位置。
执行上面的命令后将会进入GDB命令行界面:
(gdb)
在GDB命令行界面中远程连接gdbserver
target remote :1234
1234代表端口号。
在GDB命令行界面中设置库搜索路径
set solib-search-path $SYSTEM_LIB:$SYSTEM_BIN:$PLATFORMS_21_LIB
这一步是为了本机上GDB远程调试时可以找得到符号。
GDB常用命令
查看寄存器
info reg
设置和查看断点
设置:
b <符号名>
b <文件路径>:行号
查看:
info break
一次性断点
tb <符号名>
继续执行
c
单步跟踪
n
步入
s
打印变量值
print <变量名>
print也可以打印指针值:print *<指针变量名>。
查看当前执行位置
where