使用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!

时间: 2024-10-20 22:53:18

使用ndk-gdb调试AS下的Native程序的相关文章

gdb调试命令

本篇摘自互联网,纯属自己学习笔记,然分享给看到我的博客的人们. 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,

GDB调试 (五)

查看运行时数据-------        在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是:        print <expr>    print /<f> <expr>        <expr>是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),<f>是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x

gdb 调试学习

gdb 是unix/linux 系统下的程序调试工具,和IDE(如VS, Eclipse等)的图形化调试工具相比,gdb在断点,跟踪显示方面有着不足,但是它在某些方面比图形化调试工具更加丰富的功能. gdb 调试前提 如果希望程序能够被gdb调试,则需要在编译程序时候,指定 -g 选项. gdb 的调试和程序的release 优化一样,也存在着级别,可以手动设置.默认的gdb级别为2, 当把gdb的调试级别设置为3的时候,可以在gdb调试过程中 macro expand/exp  对程序中的宏定

用GDB 调试Java程序

陈皓 http://blog.csdn.net/haoel 背景 想要使用GDB调试程序,就需要用GNU的编译器编译程序.如:用GCC编译的C/C++的程序,才能用GDB调试.对于Java程序也是一样的,如果想要用GDB调试,那么就需要用GNU的Java编译器--GCJ来编译Java程序. 目前,很多Linux都不会预装Sun的JVM,取而代之是使用GNU的开源编译器来编译和运行Java程序.比如RedHat和Ubuntu,其默认安装都是使用GNU的Java编译器(gcj)和解释器(gij).当

gcc编译与gdb调试简要步骤

http://blog.chinaunix.net/uid-24103300-id-108248.html 一.Linux程序gcc编译步骤: Gcc编译过程主要的4个阶段: l 预处理阶段,完成宏定义和include文件展开等工作:(.i) l 根据编译参数进行不同程度的优化,编译成汇编代码(.s.S) l 用汇编器把汇编代码进一步生成目标代码(.o) l 用连接器把生成的目标代码和系统或用户提供的库连接起来,生成可执行文件 格式: l gcc -E test.c//预处理阶段 l Gcc -

比较全面的gdb调试命令

用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,互相不能调用,很不利于各种软件的相互集成.在这里并不是要和Win

gdb调试C程序

gdb调试 概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC.BCB的图形化调试器更强大的功能.所谓“寸有所长,尺有所短”就是这个道理. 一般来说,GDB主要帮忙你完成下面四个方面的功能: 1) 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序. 2) 可让被调试的程序在你所指定的调置的断点处停住.(断点可以是条件表达式) 3) 当

经典的GDB调试命令,包括查看变量,查看内存

经典的GDB调试命令,包括查看变量,查看内存 在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是: print print / 是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x. 一.表达式 print和许多GDB的命令一样,可以接受一个表达式,GDB会根据当前的程序运行的数据来计算这个表达式,既然是表达式,

第02课:启动GDB调试

使用GDB调试程序一般有三种方式: gdb filename gdb attach pid dgb filename corename 也对应这本节课的核心内容: 直接调试目标程序 附加进程 调试core文件 接下来我们逐一讲解. 2.1直接调试目标程序 在开发阶段或者研究别人的项目时,当编译成功生成目标二进制文件后,可以使用gdb filename直接启动这个程序的调试,其中filename是需要启动的调试程序文件名,这种方式是直接使用GDB启动一个程序进行调试.注意这里说的启动一个程序进行调