zoukankan      html  css  js  c++  java
  • 使用ndk-gdb调试android native程序

    《使用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.配置目标程序

    1. C++代码必须使用ndk-build编译,传入参数NDK_DEBUG=1。编译完成后,会在lib目录下生成gdbserver,供后续调试使用。
    2. 设置AndroidManifest.xml,在application项下面设置android:debuggable="true"
        <application
            android:debuggable="true">
            ...
        </application>

    注意:是application项下面,别写到其他地方去了,我就被坑过。
    3. 打包生成apk,然后安装到手机上。

    2.启动ndk-gdb

    1. 在手机上启动上一步骤安装的程序,准备让ndk-gdb挂接。注意:手机需要root,否则ndk-gdb可能没有相关权限启动gdbserver。
    2. 进入工程目录,执行$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重新执行。
    3. 如果启动成功,程序会被中断,在控制台上就可以输入gdb的命令了。
    4. 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

    更多gdb用法,可以参考文章尾部的链接[2]

    参考链接:

    1. nkd-gdb官网:http://developer.android.com/ndk/guides/ndk-gdb.html
    2. gdb常用命令:http://elinux.org/GDB
  • 相关阅读:
    一步一步精通 Windows Sockets 网络编程(2)
    一步一步精通 Windows Sockets 网络编程(3)
    一步一步精通 Windows Sockets 网络编程(连载)
    Sql Server 创建远程连接
    js 去字符串两边空格
    C# .Net RSA加解密以及SHA1WithRsa签名生成及验签
    win10远程桌面怎么保存密码?win10让远程桌面记住密码的方法
    mysql skipgranttables 无法启动
    C# .Net WebClient http及https请求
    iis8 是没有读系统的短日期格式
  • 原文地址:https://www.cnblogs.com/ygxsk/p/7693977.html
Copyright © 2011-2022 走看看