您的位置:首页 > 移动开发 > Android开发

使用ndk-gdb调试android native程序

2016-03-27 20:08 441 查看
《使用ndk-gdb调试android native程序》

作者: 游蓝海

文章链接: http://blog.csdn.net/you_lan_hai/article/details/50993437

转载请注明出处

虽然Eclipse可以调试android native程序,但是Eclipse启动和监测的线程太多(感觉都上百个了),导致数据同步很慢,还没走几步就卡崩了。

网上也有很多人向google反馈过调试太慢的问题,但是google给的回复是,他们没觉得native调试太慢,是被Eclipse搞慢的,他们建议使用ndk-gdb进行调试。

我以前没用过gdb调试,感觉很低效,比起Xcode的调试功能,android真是太落后了,没有合适的native调试工具。无奈代码在ios上运行正确,在android上就崩了,该面对的还是要面对。遂作此文,记录下调试过程。

我使用的操作系统是OSX,Windows系统上的操作类似,但需要安装Cygwin。

1.配置目标程序

C++代码必须使用
ndk-build
编译,传入参数
NDK_DEBUG=1
。编译完成后,会在lib目录下生成gdbserver,供后续调试使用。

设置AndroidManifest.xml,在application项下面设置
android:debuggable="true"


<application
android:debuggable="true">
...
</application>


注意:是application项下面,别写到其他地方去了,我就被坑过。

3. 打包生成apk,然后安装到手机上。

2.启动ndk-gdb

在手机上启动上一步骤安装的程序,准备让ndk-gdb挂接。注意:手机需要root,否则ndk-gdb可能没有相关权限启动gdbserver。

进入工程目录,执行
$NDK_PATH/ndk-gdb
。ndk-gdb会分析当前目录下的AndroidManifest.xml文件,提取包名,并且判断是否是debuggable模式,然后自动连接包名对应的程序上。

你的工程可能还需要提供参数
NDK_MODULE_PATH=your_module_path


如果启动失败,设置上参数
--verbose
,可以看到更详细的log。

如果log显示
ERROR: The device does not support the application's targetted CPU ABIs!
,这是ndk-gdb脚本的bug,提取
COMPAT_ABI
失败了,换成python脚本
$NDK_PATH/ndk-gdb.py
重新执行。

如果启动成功,程序会被中断,在控制台上就可以输入gdb的命令了。

ndk-gdb的部分参数说明

参数说明
--verbose
开启verbose模式,可以看到ndk-gdb输出的详细调试信息。如果gdb总是启动失败,可以加上该参数,查看错误的原因。
--force
强制结束掉已经存在的调试连接。
--nowait
app直接启动,不用等待调试器。默认情况下,app启动之后,会等待调试器挂接(attach)。该参数可与–delay配合使用。
--delay=<secs>
延迟若干秒之后,再挂接调试器。如果希望程序完全运行起来之后再挂接调试器,可以设置上
--nowait
参数,并且
--delay
设置上希望延迟的时间。
--start
重新启动app用于调试。默认情况下,gdb会挂接到已经启动了的app上。但是,直接挂接已经启动了的app可能会失败。
--launch=<name>
--start
功能相似。不同之处在于,
--launch
可以指定Android Activity。如果你的app存在多个Activity,该参数就比较合适。某些情况下,
--start
会获取到错误的Activity名称,也会导致启动失败。

3.使用gdb调试命令

ndk-gdb启动成功后,可能会频繁的出现SIG33中断,这个中断不是异常,使用下面的命令忽略掉就可以了。

(gdb) handle SIG33 nostop
(gdb) handle SIG33 noprint


某些情况下,在启动的时候,会一直报段错误(SIGSEGV),并且没有调用堆栈。此时可以一直使用命令
c
跳过,直到执行正常。

常用命令说明

命令名称命令说明
查看调用堆栈backtrace简写bt。如果程序中断或者崩溃,可以使用该命令查看当前的函数调用堆栈。然后结合frame参数,定位到对应的层次中。
跳转到堆栈frame frame-number简写f。如果想查看某层堆栈的变量,可以用该命令跳转到相应的层。
设置断点break file:linefile为文件名称,可以不含路径。line为行号
列出断点info breakpoints列出所有的断点,每个断点对应一个编号。可以使用delete命令删除编号对应的断点。
删除断点delete breakpoint-numberbreakpoint-number为断点编号。
单步进入step简写s。逐个命令执行。
单步执行next简写n。逐行执行。
跳出当前函数finish
继续执行continue简写c。程序恢复执行,直到遇到下个断点或者异常。
查看变量print variable简写p。打印变量值、地址、寄存器等,也可以执行函数,变量赋值等。
设置变量set var name=value
更多gdb用法,可以参考文章尾部的链接[2]

参考链接:

nkd-gdb官网:http://developer.android.com/ndk/guides/ndk-gdb.html

gdb常用命令:http://elinux.org/GDB
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ndk-gdb ndk 调试 android