首页 > 其他分享 >[转]好消息,android平台从froyo 2.2开始支持jni单步调试了

[转]好消息,android平台从froyo 2.2开始支持jni单步调试了

时间:2023-06-08 20:36:19浏览次数:44  
标签:r4 ndk hello gdb froyo 单步 2.2 jni android


好消息,android平台从froyo 2.2开始支持jni单步调试了


北京理工大学  20981  陈罡
一、写在前面的话 (可以理解为废话)
前 段时间从网上看了google的io大会,亲眼看到了google在it技术发展和创新领域所做的工作(在此也问候一下apple公司的美术家门,你们辛 苦了)。虽然google认为未来pc上只可能存在两种程序——browser和game,但是就目前来看,pc平台上的application还是有一 定的市场的,html5的推广和应用毕竟是需要一定时间的(第一个吃螃蟹的人,可能会吃的很好,但是如果第一个吃蘑菇的人呢?如果吃到的是毒蘑菇呢?业内 都在等,在看,一旦别人吃的还行,那个时候才会蜂拥而上)。这就好像虽然google在大力鼓吹html5的各种特性,可是自己仍然在android平台 上添加对flash 10.0的支持一样(用原话说:“hey,man,people use flash!”),从这一点来看google相对更加亲民一些,而apple则更加激进一些(这并不是说谁好,谁不好,偶也喜欢激进一点的风格拉,毕竟 iphone颠覆了整个手机行业,一下子把ui设计的准绳拉得很高,这让一些诸如曾经卖木头的公司很郁闷)。

言归正传,froyo新增了 许多功能,也改进了很多地方,但是偶认为对开发者来说最值得高兴的事情就是android 2.2修改了dalvik的运行机制(应该说是加入了类似jit引擎的东西吧),可以让程序运行得更快,另外就是支持jni的单步调试(看到这个特性偶的 眼泪是哗哗的,想当年面对着jni模块输出的密密麻麻的log偶痛苦地闭上了眼睛。。。)。其他的诸如app to sd,无线ap,exchange,push api,语音翻译,搜索,等等这些都是锦上添花的事情了。

从偶的观点来看——速度才是硬道理!

要不然真是可惜了nexus one那1ghz的处理器了。

二、ndk-r4带给我们的惊喜
别的不说啥了,把changes.txt的重要的部分给翻译一下发出来就好了(英语好的朋友可以直接忽略)。
changes.txt的原文在android-ndk-r4/docs目录下:
重用要的BUG修正:
(1)<fenv.h>这个头文件在以前版本的ndk中放置的位置不对,这将导致在一些常规的编译过程中无法找到该文件进而引起编译失败。(这个问题在ndk-r4已经修正了)

重要的变化:
(1)在win32环境下,ndk需要配合1.7或者更高版本的cygwin使用。目前,已经官方认定在cygwin 1.5的环境下,ndk有可能不会正常工作。
(2)进一步简化编译过程:
开 发者不再需要进入ndk的根目录,然后运行build/host-setup.sh脚本来初始化环境变量或者修改$NDK_ROOT/apps目录下面的 任何文件了,取而代之的是在编译jni模块的时候,只需要在jni目录下面运行一个命令“ndk-build”即可自动完成编译过程(这个脚本甚至连子目 录下面的模块都可以自动编译)。
ndk-build脚本的具体使用方法,可以参见overview.txt和ndk-build.txt这两个文档。
注意:
出 于兼容性考虑,开发者仍然可以在"$NDK_ROOT/apps/<name>"中创建工程。但是ndk的示例工程已经从apps目录转移到 了"samples/<name>"目录下,而且在编译jni模块的时候,一定要用"ndk-build"脚本进行编译。
(3)引入更加方便的调试手段:
从android 2.2开始(同样适用于未来更高版本的android系统),开发者可以使用“ndk-gdb”工具很方便地对native的模块进行调试。具体的调试方法参见“ndk-gdb.txt”文档。(这也是偶本文要讲的内容了)
(4)支持硬件的FPU:
根据ARMv7-a级别的设备,可以指定ndk生成新的“armeabi-v7a” ABI的机器码。
注意:
ndk 在默认的配置下,仍然会生成旧的“armeabi” ABI(基于ARMv5TE指令集)的机器码,此配置可以在目前所知的所有android的系统image下工作。(费了半天劲,其实就是说ndk默认生 成的模块兼容性比较好,而新引入的功能则可以经过优化以后性能更高,可以使用更先进的arm指令集)。

修改ndk生成机器码的配置主要通过修改mk文件的APP_ABI变量完成,具体的修改方法请参考application-mk.txt文档。

(5)提供了一个小型的“cpufeatures”静态库,可以通过该库在jni运行时得到当前cpu支持的特性。该库支持从android 1.5开始所有的平台。关于该库的更详细的信息,请参考cpu-features.txt文档。

(6) 支持可选的ARM Advanced SIMD (a.k.a. NEON)特性,吧啦吧啦吧啦。下面几个cpu相关的特性,还是给对硬件优化感兴趣的朋友们研究好了。需要提一嘴的是,samples目录下面有一个叫做 hello-neon的范例,就是演示cpu features的,感兴趣的朋友们不要错过。

(7)添加 了<android/bitmap.h>头文件,可以提供jni模块对传入的android.graphics.Bitmap对象的直接操作 (这个功能太有用了,否则,在jni里面操作Bitmap对象那叫一个麻烦。。。),使用方法可以参考samples目录下的bitmap-plasma 示例程序。

另外,就是支持一些确保不会让模块被内核执行的一些安全功能以及一些bug修正,最后再提一句就是ndk-r4已经开始支持.s结尾的纯汇编代码编译了(之前的之能够支持嵌入式的汇编支持),骨灰级别的玩家注意了!

最后就是一些c和c++库的头文件的修改和微调,在此不再聒噪。

三、开始体验ndk-r4
看了上面的修改变化,想必大家都开始手痒了吧?!好的,马上就开始安装这个ndk-r4,当然,前提是sdk一定要更新到android 2.2这个平台对应的最新版本,当然相应的adt也要升级喔!

老规矩,偶的所有介绍都是基于linux平台的。

1、下载ndk-r4
官方的下载地址当然是:developer.android.com/sdk/ndk/index.html啦,不过由于和谐的原因我们下载不了。可以通过代理的方式去下载,相信大家总会有办法下载下来的。

2、安装ndk-r4
其实很简单了,只用一个命令就行:
$unzip android-ndk-r4-linux-x86.zip
解压完毕后会看到一个叫做android-ndk-r4的目录,这个目录需要export到当前的PATH环境变量里面去:
$export PATH=~/android-ndk-r4:$PATH
然后这个ndk就安装好了。(不要问我怎么不运行build/host-setup.sh脚本,那东西已经在r4被淘汰掉了)

3、编译个hello world看看
$cd ~/android-ndk-r4/samples/hello-jni/
$ndk-build
Gdbserver      : [arm-eabi-4.4.0] /home/wayne/android-ndk-r4/samples/hello-jni/libs/armeabi/gdbserver
Gdbsetup       : /home/wayne/android-ndk-r4/samples/hello-jni/libs/armeabi/gdb.setup
Gdbsetup       : + source directory /home/wayne/android-ndk-r4/samples/hello-jni/jni
Install        : libhello-jni.so => /home/wayne/android-ndk-r4/samples/hello-jni/libs/armeabi
如果看到上面的输出,呵呵,恭喜恭喜,jni的so库已经编译成功了。

4、生成一个apk看看吧
这一步比较烦,要求必须安装了ant以及最新的android sdk,并且把$ANDROID_SDK/tools和ant的bin目录也export到PATH环境变量里面才行。
在此偶只贴出来偶的配置:
$export PATH=/usr/local/apache-ant-1.8.1/bin:$PATH
$export PATH=/home/wayne/android-sdk-linux_86/tools:$PATH
当然了,这些对PATH的修改,可以直接写到/etc/profile文件中,下次一进入shell就会自动准备好,在此按下不表。

好了,开始生成apk

$cd ../          
 $android update project --path hello-jni          
 $cd hello-jni          
 $ant debug          
 Buildfile: /home/wayne/android-ndk-r4/samples/hello-jni/build.xml          
     [setup] Android SDK Tools Revision 6          
     [setup] Project Target: Android 2.2          
     [setup] API level: 8          
     [setup] WARNING: Attribute minSdkVersion in AndroidManifest.xml (3) is lower than the project target API level (8)          
     [setup] Importing rules file: platforms/android-8/ant/ant_rules_r2.xml          

 -compile-tested-if-test:          

 -dirs:          
      [echo] Creating output directories if needed...          

 -resource-src:          
      [echo] Generating R.java / Manifest.java from the resources...          

 -aidl:          
      [echo] Compiling aidl files into Java classes...          

 compile:          
     [javac] /home/wayne/android-sdk-linux_86/platforms/android-8/ant/ant_rules_r2.xml:255: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds          
     [javac] Compiling 1 source file to /home/wayne/android-ndk-r4/samples/hello-jni/bin/classes          

 -dex:          
      [echo] Converting compiled files and external libraries into /home/wayne/android-ndk-r4/samples/hello-jni/bin/classes.dex...          

 -package-resources:          
      [echo] Packaging resources          
  [aaptexec] Creating full resource package...          

 -package-debug-sign:          
 [apkbuilder] Creating HelloJni-debug-unaligned.apk and signing it with a debug key...          
 [apkbuilder] Using keystore: /home/wayne/.android/debug.keystore          

 debug:          
      [echo] Running zip align on final apk...          
      [echo] Debug Package: /home/wayne/android-ndk-r4/samples/hello-jni/bin/HelloJni-debug.apk          

 BUILD SUCCESSFUL          
 Total time: 7 seconds


这些命令运行完毕后,如果看到上面的输出,代表生成的apk是正常的,然后就是安装程序。

5、安装和调试程序
偶是android的fans,因此,nexus one早早就刷了froyo 2.2,因此直接在手机上装了。鉴于很多朋友没有nexus one,偶在下面还是用emulator做演示比较好。

首先,运行android命令,新建一个2.2的emulator。(建立模拟器的方法不再聒噪,如下图所示)



其次,进入android-ndk-r4/samples/hello-jni/bin目录,应该能够找到一个apk安装包,直接安装即可。

$adb install ./HelloJni-debug.apk

1201 KB/s (78926 bytes in 0.064s)

        pkg: /data/local/tmp/HelloJni-debug.apk

Success

看到Success,就代表已经安装成功了。


然后,注意,忍受了偶上面那么多废话的朋友们,下面就是关键的地方了!

$cd ~/android-ndk-r4/samples/hello-jni/

$ndk-gdb

此时,观察模拟器的反应,hoho,是不是看到模拟器里面的hello-jni程序自己打开了?!



然后就是ndk-gdb自动进入了一个命令行提示符的状态:

and track explicitly loaded dynamic code.          
 warning: shared library handler failed to enable breakpoint          
 0xafd0eb08 in ?? ()          
 (gdb) list          
 1       /*          
 2        * Copyright (C) 2009 The Android Open Source Project          
 3        *          
 4        * Licensed under the Apache License, Version 2.0 (the "License");          
 5        * you may not use this file except in compliance with the License.          
 6        * You may obtain a copy of the License at          
 7        *          
 8        *      http://www.apache.org/licenses/LICENSE-2.0          
 9        *          
 10       * Unless required by applicable law or agreed to in writing, software          
 (gdb) list          
 11       * distributed under the License is distributed on an "AS IS" BASIS,          
 12       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.          
 13       * See the License for the specific language governing permissions and          
 14       * limitations under the License.          
 15       *          
 16       */          
 17      #include <string.h>          
 18      #include <stdlib.h>          
 19      #include <jni.h>          
 20          
 (gdb) list          
 21      static void upper_str(char *s, int len) {          
 22        int i ;          
 23        for(i = 0 ; i < len ; i++) {          
 24          if((s[i] >='a') && (s[i] <='z')) {          
 25            s[i] = s[i] - 'a' + 'A' ;          
 26          }          
 27        }          
 28      }          
 29          
 30      /* This is a trivial JNI example where we use a native method          
 (gdb)

在linux做过开发的朋友们一定对gdb的命令行模式非常熟悉吧?到这里就一切豁然开朗了。


可能有朋友要问,怎么有一大堆的warning,好象是说什么符号找不到?

其 实这很简单,android 2.2版本的模拟器自然是release版啦,debug版的一定慢得要死,所以,很多函数的库和符号是没有的,因此,在gdb里面根本找不到也是有情可 原的,只要忽略掉这些就行了(偶是多么容易满足的人啊!在此赞叹一下。另外插一句,如果有人真的爱钻牛角尖,要弄清楚这个的话,可以尝试用android 的源代码编译一个debug版的android,偶试过的可以调试native的程序,而且也没有这些warning,不过又会是一个痛苦的过程)。


然后就是常规的gdb调试命令了。

list-显示代码

x-查看内存

p-查看变量

b-设置断点

cont-程序继续运行

s-单步执行,但可以跟踪进入函数

n-单步执行,但不会进入函数

吧啦吧啦吧啦,关于gdb的使用,偶就不再聒噪了,网上相关说明非常多。


这里需要提醒一下,相信细心的朋友已经看到怎么偶的界面跟大家的hello-jni不一样?!


android 的在线调试的基本原理并不是本地的gdb程序,而是在模拟器(或者真机)上启动了一个叫做gdb-server的东西,通过adb的tcp中转,让开发者 本机的gdb与模拟器(或者真机)上的gdb-server进行连接,然后进行调试。这个过程相对比较繁琐,感兴趣的朋友可以参考ndk-gdb这个脚本 (hoho,想当年偶调试native程序的时候,是自己写的连接gdb和gdb-server的脚本,期间问候了无数次google的祖宗多辈,在此按 下不表)


在hello-jni里面,jni函数的调用是放在activity的oncreate函数中的,也就是说一程序一启动就已经调 用了jni,而在pc端的gdb联上模拟器的gdb-server的时候,jni已经运行完了,而且oncreate函数也不是随便说调用就调用的,因 此,在什么地方下断点呢?!偶就想了个土法,那就是修改一下原有的hello-jni程序,在里面添加一个小button,按下这个button的时候才 会调用jni的函数。


如此一来,使用ndk-gdb的时候只是启动了activity,并不会真的调用jni函数,当偶把函数的断点都设置好以后,再运行“cont”命令,然后单击一下按钮,这个时候才会真的跑到断点里面来。


为了大家方便起见,偶把修改过后的hello-jni的源代码给贴出来。

希望本文能够对android平台开发的朋友们有所帮助。


标签:r4,ndk,hello,gdb,froyo,单步,2.2,jni,android
From: https://blog.51cto.com/u_16125990/6442955

相关文章

  • 微信小程序开发笔记 进阶篇⑤——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之前
    文章目录一、前言二、前端代码wxml三、前端代码js四、后端java五、程序流程六、参考一、前言微信小程序开发笔记——导读大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机号码。但是,因为小程序用户的手机号码属于重要信息,为了安全,所以需要如下一系列较为复杂的方法和......
  • 微信小程序开发笔记 进阶篇⑥——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之后
    文章目录一、前言二、前端代码wxml三、前端代码js四、后端java五、程序流程六、参考一、前言微信小程序开发笔记——导读大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机号码。但是,因为小程序用户的手机号码属于重要信息,为了安全,所以需要如下一系列较为复杂的方法和......
  • 2.2类神经网路训练不起来怎么办 (二): 批次 (batch) 与动量 (momentum)
    1.Batch(批次)对抗临界点的两个方法就是batch和momentum  将一笔大型资料分若干批次计算loss和梯度,从而更新参数.每看完一个epoch就把这笔大型资料打乱(shuffle),然后重新分批次.这样能保证每个epoch中的batch资料不同,避免偶然性.epoch是指将数据集分成batch后,......
  • 最完美WIN11_Pro_22H2.22631.1830软件选装纯净版VIP41.9
    【系统简介】=============================================================1.本次更新母盘来自UUP_WIN11_PRO_22H2.22631.1830。进一步精简优化调整。2.只为呈现最好的作品,手工精简优化部分较多。3.OS版本号为22631.1830。个别要求高的就下MSDN吧,里面啥功能都有。4.集成《DrvCeo......
  • 2015.4.22.20.46_ecilipse_8.30_Eclipse 10个最有用的快捷键_0.01
    Eclipse中10个最有用的快捷键组合一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合。通过这些组合可以更加容易的浏览源代码,使得整体的开发效率和质量得到提升。1.ctrl+shift+r:打开资源这可能是所有快捷键组合中最省时间的了。这组快捷键可以让你打开你的......
  • 2014.4.19.12.27_switch_8.28_java switch语句使用注意的四大细节_0.01
    javaswitch语句使用注意的四大细节很多朋友在使用javaswitch语句时,可能没有注意到一些细节,本文将详细介绍使用javaswitch语句四大要点,需要的朋友可以参考下。switch语句的格式如下:(它的功能是选出一段代码执行)switch(整数选择因子){case整数值1:语句;break;case整数值......
  • hbase-2.2.3集群安装1
    安装程序,解压拷贝先设定hbase安装目录/home/opt/hbase-2.2.3tar-xvzfhbase-2.2.3.tar.gzmvhbase-2.3.3/home/opt配置环境变量vim/etc/profile添加如下exportHBASE_HOME=/home/opt/hbase-2.2.3exportPATH=$PATH:$HBASE_HOME/binsource/etc/profile 创建hbase的pids......
  • HBase-2.2.3集群安装
     /不需要手动创建,系统程序会自动创建hdfsdfs-mkdir-p/hbasehdfsdfs-chmod-R777/hbasehdfs://hadoop34:9000/hbase先设定hbase安装目录/home/opt/hbase-2.2.3tar-xvzfhbase-2.2.3.tar.gzmvhbase-2.2.3/home/opt配置环境变量vim/etc/profile添加如下ex......
  • postgresql9.2.24安装
    1、yum安装 yum install -y postgresql-server postgresql-contrib 2、初始化 postgresql-setup initdb 3、挂载数据盘 ln -s /data/pgsql /var/lib/pgsqlchown -R postgres:postgres pgsql 4、修改配置文件pg_hba.conf localall......
  • 2.2. 继承与多态
    继承和多态是面向对象编程的两个重要概念,它们使得我们可以创建更加通用、可扩展的代码。2.2.1.继承继承是一种创建新类的方式,新类(子类)从现有类(父类)继承属性和方法。子类可以重写或扩展父类的功能。要创建一个子类,可以使用 extends 关键字:classSubClassNameextendsParent......