首页 > 代码库 > NDK官方开发指南翻译之 NDK_GDB

NDK官方开发指南翻译之 NDK_GDB

这几天看JNI,没有基础,那真是难受……把看到的相关资料记录一下,也分享给初学者。

ndk-gdb Overview

重要:如果你要调试线程相关的程序,请阅读下面的‘Thread Support’部分。


1.用法:

-------------


Android r4引入了一个叫着‘ndk-gdb’的脚本,能够非常简单的为NDK生成的机器码启动一个debugsession


这个脚本位于NDK的顶层目录下,它必须从你应用程序的目录或者子目录下,用命令行的方式来调用。例如:


cd $PROJECT

$NDK/ndk-gdb


$NDK指向你NDK的安装路径。你可以创建一个别名或者把$NDK加入到你的环境变量PATH中,这样可以避免每次都要输入完整的路径名。



重要:本地调试只有在以下所有条件都满足时才能工作:


1.你的应用程序必须用‘ndk-build’脚本编译。


用之前的方式‘make APP=<name>’编译,NDK是不支持的。


     2.你的应用程序必须是可调试的:


换句话说,AndroidManifest.xml<application>须设置android:debuggabletrue


                 3.  你的应用程序必须运行在Android 2.2或者更高的版本中:


ndk-gdb运行在Android 2.2版本之前是不行的。这并不意味着,你的应用程序的目标API必须是2.2+,只是debugging session只能运行在2.2+的设备或者模拟器上。



非常非常非常重要!!


如果你使用Eclipse ADT插件编译应用程序,必须确保使用0.9.7或之后的版本。


如果你使用‘ant’编译工具,必须确保使用的是SDK平台组件的最新版本。下面是最低版本的要求:


       Android 1.5    r4

       Android1.6    r3

       Android2.1    r2

       Android2.2    r1


这些都可以通过SDK的更新来获得。


如果这些条件不满足,生成的apk将不会包含必要的支持文件,本地调试将不能工作。



如果发现了问题,‘ndk-gdb’会处理许多错误情况和存储错误信息。例如:


-检查adb是否在你的path中。


-检查你的应用程序在manifest中是否声明了debuggable


-检查设备上已经安装的具有相同包名的应用程序是否是可调试的。


默认情况下,ndk-gdb会搜索已经正在运行的应用程序进程,如果没有找到的话会报错。但是你可以在启动debugging session之前,使用--start--launch=<name>选项来自动启动activity


gdb成功attach到你应用程序的进程中,在session建立后,ndk-gdb会有一个GDB提示:在生成的本地库中查找源文件和symbol/debug versions


你可以用‘b <location>’设置断点,用‘c’(continue)继续执行。更多的命令请查看GDB手册。


重要:当退出GBD提示,应用程序的调试进程就会停止!这是gdb的一个限制。


重要:当gdb找不到系统库(如libc.so, libstdc++.so, liblog.so, libcutils.so等)的时候,GDB停止退出前,会列出一长串的错误信息。


这是正常的,因为在你的开发机器上,没有这些库的symbol/debug versions来对应你的目标设备。你可以安全的忽略这些信息。



2. 选项:

------------


你可以用‘ndk-gdb --help’命令列出这些选项:


 --verbose:

打印native debuggingsession启动时的详细信息。当你不能连接、ndk-gdb打印的错误信息不够的时候,才需要它来调试问题。


--force

默认情况下,如果发现另外一个nativedebugging session运行在同一台设备上,ndk-gdb会崩溃。使用--forcekill掉那个session,然后启动一个新的session替换它。注意调试的程序不会被kill,将会再一次stopped


  --start:

默认情况下,ndk-gdb会试图attach到一个正在运行的应用程序的实例上。你可以在debugging sessiong之前,使用--start来显示的启动你的应用程序。


注意:这个选项会启动manifest中第一个launchableactivity,使用--launch=<name>可以启动其他的activity--launch-list可以列出所有这样的activity

  --launch=<name>:

除了可以启动指定的activity外,其他的和start类似。如果你的manifest定义了很多launchableactivity,这个选项是比较有用的。


--launch-list

列出manifest中所有launchableactivity。使用--start时,第一个launchableactivity被启动。


--project=<path>:

指定应用程序的工程所在目录。如果你不想cd到你工程的目录中,这个选项是比较有用的。


--port=<port>

默认情况下,ndk-gdb使用本地TCP端口5039连接到debugged的应用程序。通过使用不同的端口,在同一台开发机器中,可以在不同的设备/模拟器上运行调试程序。


--adb=<file>:

如果不在你的path中,可以指定adb工具的路径。


-d-e-s <serial>

这些标志和ADB类似,可以处理多台设备/模拟器连接到你机器上的情况。

-d连接到一个单独的物理设备

-e连接到一个单独的模拟

-s连接到<serial>指定的真机或者模拟器,<serial>是用‘adb  devices’命令列出的设备           的名称。


你也可以定义ADB_SERIAL环境变量来指定你的设备,不需要使用这个选项。



--exec=<file>:

 -x<file>:

连接到调试进程后,会运行在<file>文件中找到的GDB初始化命令。当你要做一些重复的事情,这是非常有用的。例如建立一序列的断点,然后自动恢复执行。



3.必要条件

---------------------


目前‘ndk-gdb’需要运行在Unix shell上。这意味着在Windows系统中必须运行在Cygwin上。我们希望在以后的NDK版本中能够摆脱这个限制。


NDK的其他要求:例如 GNU Make3.81或更高版本。



4. 线程支持:

------------------


如果你的应用程序运行在Android 2.3之前,ndk-gdb不能正确的调试本地线程,debug的时候只能把断点打在主线程中,完全会忽略其他线程的执行。


造成这个问题的最初原因是很复杂的,本质上是在这个平台上不幸有一个bug,而这个是最近才发现的。


运行时,NDK自带的gdbserver二进制文件有特殊的代码来检测这个条件,并且会自动调整它的行为(换句话说,当编译代码的时候,你不需要任何的特殊操作)。


这意味着在实践中:


如果你运行在Android 2.3,或者2.3之前的平台但是已经修复了这个bug,你可以自动的调试本地线程。


如果不是,你只能在主线程中调试(像前面所说的)。当启动ndk-gdb(在gdb prompt之前),你会看到下面的信息:


     Thread debugging is unsupported on this Android platform!


如果你在非主线程中执行的函数打了断点,程序会退出,同时GDB会输出以下信息:


     Program terminated with signal SIGTRAP, Trace/breakpoint trap.        

    The program no longer exists.

NDK官方开发指南翻译之 NDK_GDB