使用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。
设置AndroidManifest.xml,在application项下面设置
注意:是application项下面,别写到其他地方去了,我就被坑过。
3. 打包生成apk,然后安装到手机上。
进入工程目录,执行
你的工程可能还需要提供参数
如果启动失败,设置上参数
如果log显示
如果启动成功,程序会被中断,在控制台上就可以输入gdb的命令了。
ndk-gdb的部分参数说明
某些情况下,在启动的时候,会一直报段错误(SIGSEGV),并且没有调用堆栈。此时可以一直使用命令
常用命令说明
更多gdb用法,可以参考文章尾部的链接[2]
gdb常用命令:http://elinux.org/GDB
作者: 游蓝海
文章链接: 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:line | file为文件名称,可以不含路径。line为行号 |
列出断点 | info breakpoints | 列出所有的断点,每个断点对应一个编号。可以使用delete命令删除编号对应的断点。 |
删除断点 | delete breakpoint-number | breakpoint-number为断点编号。 |
单步进入 | step | 简写s。逐个命令执行。 |
单步执行 | next | 简写n。逐行执行。 |
跳出当前函数 | finish | |
继续执行 | continue | 简写c。程序恢复执行,直到遇到下个断点或者异常。 |
查看变量 | print variable | 简写p。打印变量值、地址、寄存器等,也可以执行函数,变量赋值等。 |
设置变量 | set var name=value |
参考链接:
nkd-gdb官网:http://developer.android.com/ndk/guides/ndk-gdb.htmlgdb常用命令:http://elinux.org/GDB
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories