gdb硬件断点android,Android中app调试:gdb如何在动态链接库中设断点

这种方法适用于想调试android中app所用到的.so库的情况,尤其是载入库后一会就出问题的情况。如果直接起gdb载入动态链接库的符号表,这时符号地址是不对的。本文中以某app为例,因此具体函数名依实例肯定有所不同。

第一步:Dev Tools -> Development Settings ,将要调的程序设为wait for debugger。这时程序一起来就会停住,等待jdb信号。详见(http://www.voidcn.com/article/p-mfrxmgry-brx.html)。

第二步:启动jdb,用ps找出pid(假设为1476)。然后打开~/.jdbrc(没有的话创建一个),断点设在载入动态库的时候:

stop in java.lang.System.loadLibrary

保存退出后执行:

$adb forward tcp:29882 jdwp:1476

$jdb -attach localhost:29882

jdb启动后会自动读./jdbrc设断点,一般情况下会出现类似下面的显示:

jzj@jzj-desktop:~$ jdb -attach localhost:29882

Set uncaught java.lang.Throwable

Set deferred uncaught java.lang.Throwable

Initializing jdb ...

> *** Reading commands from /home/zjin/.jdbrc

It will be set after the class is loaded.

> Set breakpoint java.lang.System.loadLibrary

> >

第三步,等到程序因为load library而触发断点。这时可以确认下是不是我们要找的那个library。举例来说,先在jdb中查看局部变量:

<1> main[1] locals

Method arguments:

Local variables:

libName = "bigeLib"

再将程序的apk用dex2jar和jd-gui反汇编出来,找出载入.so对应的一段代码为:

package com.bz.bige;

import com.bz.bige.sound.bzSoundManager;

public class bigeJNI

{

static

{

System.loadLibrary("bigeLib");

}

}

这说明我们整对了,然后在jdb中将当前函数运行完,也就是让动态库载入完:

<1> main[1] step up

第四步,运行gdb 。如被调试程序的pid为1390的话:

在target上运行(没有gdbserver的话先从push进去):

# ./gdbserver :1234 --attach 1390

在host上运行:

$ arm-eabi-gdb -x init.gdb

载入.so的符号表,这时各符号的地址已经是relocate过的了,可以在gdb中用。关于gdb的介绍详见(http://www.voidcn.com/article/p-bazszhfx-brx.html)。

(gdb) shared

觉得有必要的话,可以用下面的命令看下函数列表:

(gdb) info functions

现在可以用函数名设断点了:

(gdb) b bzGame::init()

Breakpoint 1 at 0x4965f9fc

(gdb) b bzGame::init()

Note: breakpoint 1 also set at pc 0x4965f9fc.

Breakpoint 2 at 0x4965f9fc

(gdb) delete 2

(gdb) b bzGame::setState(std::string const&)

Breakpoint 3 at 0x496600ba

(gdb) i b

Num     Type           Disp Enb Address    What

1       breakpoint     keep y   0x4965f9fc <:init>

3       breakpoint     keep y   0x496600ba <:setstate const>

然后就可以执行continue继续了。程序到时就会停在断点处。

你可能感兴趣的:(gdb硬件断点android)