使用ndk-gdb调试AS下的Native程序

1.Create Android Studio Project

成都创新互联拥有一支富有激情的企业网站制作团队,在互联网网站建设行业深耕十载,专业且经验丰富。十载网站优化营销经验,我们已为上千余家中小企业提供了成都做网站、网站制作、成都外贸网站建设解决方案,按需定制制作,设计满意,售后服务无忧。所有客户皆提供一年免费网站维护!

  (1)新建一个Empty Activity工程:TestNDK

  (2)在工程的主Activity中加入对.so的引用.这步很关键,将System loadLibrary放入主Activity,是让程序启动后立刻加载.so,否则后面调试时,会有些麻烦

    static {

        // Load native library to invoke chreographerCallback().

        System.loadLibrary("DebugNDK");

    }

public native String  stringFromJNI();

  (3)使用javah生成相应的.h文件

     在Android Studio的Terminal窗口中输入:

cd app\src\main\java             #进入工程的app\src\main\java目录

javah stable.testndk.MainActivity  #生成.h文件,stable.testndk是包名,MainActivity是native函数所在的类名

 

接下来就可以编译NDK了,NDK编译完再回来

   

   (4)将NDK编译出的libs目录下的文件copy到app\libs目录下,如下:

   app\libs\armeabi\

                         gdb.setup

                         gdbserver

                         libDebugNDK.so

   app\libs\armeabi-v7a\

                         gdb.setup

                         gdbserver

                         libDebugNDK.so

   app\libs\mips\

                         gdb.setup

                         gdbserver

                         libDebugNDK.so

   app\libs\x86\

                         gdb.setup

                         gdbserver

                         libDebugNDK.so

 

   (5)修改app\build.gradle,在android下加入如下代码,告知jniLibs所在目录

    sourceSets {

        main() {

            jniLibs.srcDirs = ['libs']

        }

    }

   (6)rebuild工程,可以通过Build->Build APK来生成APK,然后用7Zip看一下里面是将.so打包进去了.

   

接下来进入第三步调试NDK

   

2.NDK程序的编译

(1)以 android-ndk-r10b\samples\hello-jni为模板,建立自己的NDK程序(DebugNDK).

   自己的程序需要修改Android.mk文件,增加工程及代码文件,这里将所有的hello-jni更改为DebugNDK.

   修改DebugNDK.c中的jni对外接口函数名,修改为上面使用javah到处的.h中的相应函数(Java_stable_testndk_MainActivity_stringFromJNI).

(2)编译.so

   在windows命令行下,进入工程目录(TestNDK目录),输入如下命令:

   ndk-build NDK_DEBUG=1         #注意事先要将ndk-build所在目录设置到系统环境变量中

   之后开始编译,最终在工程目录下会生成libs和obj两个目录,其中libs目录下的是发布到硬件的.so, obj下是用于调试的,后面会用到.

   

好了到此可以回到 上面个 Create Android Studio Project 的第4步了.

3.NDK调试

服务器端配置

(1)在手机上运行TestNDK程序

(2)将编译NDK程序时生成的gdbserver pull到手机(我是放到/data/data/stable.testndk.

    gdbserver在app\libs\x86\下,可以将其放到手机 /data/data/stable.testndk/lib 下

    在windows命令行下,执行:

    adb push .\app\libs\x86\gdbserver /data/data/stable.testndk/lib/

(3)在手机上启动gdbserver并attach你想调试的进程,并指定监听调试命令的端口(此端口是手机上的端口)

    在windows命令行下,执行:

    adb shell  #进入手机

    cd /data/data/stable.testndk/lib

    ps | grep stable.testndk  #查看要调试进程的PID

    gdbserver :1818 --attach 19906   #:1818是端口号,19906 是进程ID

此时,终端终端上会显示:

    Attached; pid = 19906

Listening on port 1818

   

台式机端配置

(1)使用adb做端口映射,将pc机上的端口定向到手机上gdbserver监听的端口

   adb forward tcp:1818 tcp:1818   #端口映射,将pc机的1818端口映射到手机的1818端口

(2)将设备上的app_process32拉到台式机,用于gdb调试.

   adb pull /system/bin/app_process32 ./

(3)使用android-ndk-r10b\toolchains下的gdb客户端去连接gdbserver,gdb的类型要选择针对手机平台的,由于我使用的手机是x86 PC模拟器,因此要选择:

   android-ndk-r10b\toolchains\x86-4.8\prebuilt\windows-x86_64\bin\i686-linux-android-gdb.exe

   并且gdb版本要和gdbserver一致。(可以通过--version来确认)

   

   在windows命令行下,执行如下命令,app_process32_path 表示app_process32所在目录。

   android-ndk-r10b\toolchains\x86-4.8\prebuilt\windows-x86_64\bin\i686-linux-android-gdb.exe {app_process32_path}\app_process32

   上面的命令执行完后,便进入gdb命令模式了(命令行前有(gdb)),然后执行:

   target remote :1818 #连接本地的:1234端口,此端口已经和手机的1234端口做好映射。

   set solib-search-path {solibpath}   #加载所有的动态连接库,solibpath的路径位置可以参考:NDK编译输出文件 gdb.setup 中的"set solib-search-path XXX"的目录,但注意要使用绝对目录.

   #我的是set solib-search-path D:/Android/android-ndk-r10b/samples/TestNDK/obj/local/x86

   然后用info shared命令查看是否libDebugNDK.so的符号库已经加载,我的显示的是:

   0xaabd92e0  0xaabd93c8  Yes D:\Android\android-ndk-r10b\samples\TestNDK\obj\local\x86\libDebugNDK.so   #如果符号库未加载则在Yes后有个(*).

   

(4)设置断点,开始调试

   在gdb模式,执行:

   b Java_stable_testndk_MainActivity_stringFromJNI  #设置断点

   c  #运行

   

   然后在函数调用时,断点就可以停住了! Over!


新闻名称:使用ndk-gdb调试AS下的Native程序
文章路径:http://cdiso.cn/article/phoojg.html

其他资讯