Android手机gdb调试

众所周知,linux上gdb是一个功能非常非常强大的工具,纵然使用多年,回头一看,仍然觉得还是掌握了很小很小一部分的代码。android是基于linux的平台,所以google在android上开发了很多类linux的调试工具,如arm-linux-androideabi-gcc-ar, arm-linux-androideabi-gcc, arm-linux-androideabi-g++ 等等,如果掌握了这些工具,就像外科医生可以做出出色的手术,我们可以定位android平台上的各种疑难杂症。

Android对于C/C++代码的调试方式一般选用gdb+gdbserver的方式,其中gdbserver运行在手机端,gdb运行在主机上(如linux)。

不多说,上步骤,手机以android 9.0为例, 主机以ubuntu 14.04为例。
以调试mediaserver为例;
由于mediaserver是32位的二进制程序,我们需要用32位的gdbserver来调试;
如果调试64位的二进制程序 ,需要用到64位的gdbserver64来调试。

1、手机端准备

1.1 查看gdbserver是否存在
首先查看手机端,system/bin 目录下是否存在 gdbserver二进制,
一般userdebug版本的手机都会有这个二进制,
如果没有,直接在代码的prebuilts/misc/android-arm/gdbserver目录中,找到gdbserver,push到手机中。

1.2 查看mediaserver进程号
    adb  shell ps -df |  grep mediaserver
    media        12400     1 0 15:06:09 ?     00:00:00 mediaserver

1.3 启动gdbserver

$adb shell gdbserver remote:1235 --attach 12400
spawn the-true-adb shell
xxxxx:/ # exec 'gdbserver' 'remote:1235' '--attach' '12400' 
Attached; pid = 12400
Listening on port 1235

其中,remote表示adb连接的主机ip地址,即ubuntu的ip地址, 
1235表示通讯的端口号,也可以写作其他端口号,需要保证端口号 没有被其他服务占用
12400 表示 mediaserver进程号,表示我们要监听的服务是 mediaserver
OK 手机端设置完毕

2、主机端准备

2.1 启动主机端的1235端口号

adb forward tcp:1235 tcp:1235

2.2 启动主机端的gdb
$./prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-gdb
GNU gdb (GDB) 7.6
Copyright (C) 2013 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 "--host=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
<http://source.android.com/source/report-bugs.html>.
(gdb) 

2.3 与手机握手

(gdb) target remote localhost:1235

Remote debugging using localhost:1235

0xf072ccc4 in ?? ()

2.4 设置监控的二进制

(gdb) file ~/**xxx**/out/target/product/aries/symbols/system/bin/mediaserver
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from ~/**xxx**/.repo/out-xxx-userdebug/target/product/xxx/symbols/system/bin/mediaserver...done.
注意此处我用 xxx 代替了某些路径,使用时注意使用本地对应的路径, 下同。

设置带符号表的so的路径前缀

(gdb) set solib-absolute-prefix ~/**xxx**/out/target/product/xxx/symbols
Reading symbols from    ~/**xxx**/out/target/product/xxx/symbols/system/lib/libmediaplayerservice.so...done.
Loaded symbols for     ~/**xxx**/out/target/product/xxx/symbols/system/lib/libmediaplayerservice.so
Reading symbols from ~/**xxx**/out/target/product/xxx/symbols/system/lib/libutils.so...done.
Loaded symbols for ~/**xxx**/out/target/product/xxx/symbols/system/lib/libutils.so
……
以上表示将带符号的地址读取到内存中,便于之后使用。
一些绝对路径我采用了路径我采用了 相对路径来表示,某些文件名我使用了xxx来代替,下同。

2.6 设置.so的搜索路径

(gdb) set solib-search-path ~/**xxx**/out/target/product/xxx/symbols/system/lib

OK, 至此主机端设置完毕。

3 一些操作

设置断点:
比如我想查看 GenericSource中, new FileSource的代码,加一个breakpoint断点
    (gdb) b GenericSource.cpp:427
    Breakpoint 1 at 0xf00c3a18: file frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp, line 427.

查看断点:
    (gdb) info b
    Num     Type           Disp Enb Address    What
    2       breakpoint     keep y   0xf00c3a18 in android::NuPlayer::GenericSource::onPrepareAsync() at frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp:427

在手机上点击运行时,程序走到427行会停住,gdb中输入 c 继续播放
    (gdb) c
    Continuing.

等等,也可以执行gdb的其他相关命令。
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值