为了便于在四哥大上,Android系统源码调节和测试

转载:http://www.360doc.com/content/12/1228/11/9462341_256747689.shtml

为了便于在手提式有线电话机上(Galaxy Note with
CM10),调节和测试Android4.1
系统浏览器的代码,进行代码研商,笔者把系统浏览器编写翻译成了三个独自的施用,不会跟ROM原来的连串浏览器发生争执,能够很有益地在Eclipse自个儿建立的工程里面对Java一些的代码进行跟踪调节和测试,理论上C++的有的也得以由此GDB举行调节。

经过上一篇 Android FrameWork学习Android 7.0系统源码下载\编写翻译大家了然了如何进展系统源码的下载和编写翻译工作。

 

图片 1
温馨编写翻译的库,呈现Layer边界和新闻

为了更进一步地球科学习跟商量 Android 系统源码,今天大家来讲讲哪些进展
Android
系统源码的调节,只有学会了什么开始展览系统源码的调节和测试,才能支援我们更敏捷地读书跟精通源码。

上面就以GDB调节和测试Rild为例,来注明如何调节Native进度。

先是系统浏览器能够认为分为3部分:
1,Browser.Apk 二个全职能浏览器选取
2,android.webkit 平台适配层的Java部分代码,对外提供了打包好的WebView
3,libwebcore.so
包括WebKit的代码和平台适配层C++部分的代码,libchromium_net.so
Chrome的互联网堆栈

我们理解,Android Framework
的代码首要由Java、C\C++等代码组成,因而,对于系统源码的调节,大家那边将其分为了两部分

说明

大家实在只必要后边两局地(2和3),然后加上自个儿的叁个简便的测试用外壳就足以了。
率先参考官方的文书档案,建立ROM编写翻译环境,编写翻译ROM(http://source.android.com/source/index.html)。

  • Java 相关代码的调节
  • C\C++ Native 相关代码的调节和测试
#cmd     表明该命令运行于android设备控制台上
$cmd     表明该命令运行于Linux PC控制台上
(gdb)cmd 表明该命令运行于GDB控制台上

始于创设独立的运用(home/roger/a41是本身的ROM的目录,须求替换到自个儿ROM的目录):
在Eclipse创立叁个Android工程,把android.webkit目录下的Java代码拷贝过来;
将/home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/webkit下边包车型大巴伊夫ntLogTags.java也拷贝到自个儿的工程;
因为android.webkit下的类会利用SDK中国和南美洲公然的API,大家供给缓解编写翻译错误:
创制一个User Library,并且勾选System Library的选项;
进入以下Jar包:
/home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
/home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar
/home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes.jar
在Java Build Path/Order and Export把创建的库位于最前面;
因为在大家运用中的android.webkit包跟SDK中的重名,所以大家须要转移包名,能够改成android.webkit2;
咱俩须要再行编写翻译libchromium_net.so和libwebcore.so,并且选取其它的名字,并且把其代码中运用的android/webkit/
JNI路径改成android/webkit2/保障JNI的正确:
在/home/roger/a41/external/chromium下边,把全体源文件的android/webkit/路径改成android/webkit2/;
开辟/home/roger/a41/external/chromium/Android.mk,修改库名为libchromium_net2,并且加多一行“LOCAL_MODULE_TAGS
:= optional“,具体内容见后;
再一次编写翻译chromium_net,得到libchromium_net2.so;
在/home/roger/a41/external/webkit/Source/WebKit/android上面,把全部源文件的android/webkit/路径改成android/webkit2/;
开拓/home/roger/a41/external/webkit/Android.mk,将库名改成libwebcore2.so,并且加多一行“LOCAL_MODULE_TAGS
:=
optional“(必要修改多少个地点,静态库编写翻译和动态库编写翻译),其余还要求把导入库libchromium_net改成libchromium_net2,具体内容见后;
双重编写翻译webcore,得到libwebcore2.so;
接下去我们得以把修改后的libwebcore2.so和libchromium_net2.so
push到手提式有线电电话机的rom里面,倘诺路径是/data/local(假诺没有写权限,用Root
Explorer修改);
接下来大家要求修改Java的代码,让它去加载大家温馨的库,修改的地点位于JniUtil.java和WebViewCore.java,具体内容见后(加载顺序须要变更,先加载libchromium_net2.so再加载libwebcore2.so);
说到底加上大家温馨的Test
Shell的代码,运维就OK了,假如只修改了C++的代码,重编写翻译后再Push到手提式有线电话机,然后重国民党的新生活运动行Test
Shell就足以马上见效,Java的代码能够在Eclipse里面很便宜的调节,C++的代码理论上也足以经过GDB进行调节和测试;
LOCAL_MODULE := libchromium_net2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_TAGS := optional
INTERMEDIATES := $(call local-intermediates-dir)
# Define our module and find the intermediates directory
LOCAL_MODULE := libwebcore2
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_TAGS := optional
base_intermediates := $(call local-intermediates-dir)
# Do not attempt prelink this library. Needed to keep master-gpl happy,
no
# effect in master.
# TODO: remove this when master-gpl is updated.
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libwebcore2
LOCAL_MODULE_TAGS := optional
LOCAL_LDLIBS := $(WEBKIT_LDLIBS)
# Build the list of shared libraries
# We have to use the android version of libdl
LOCAL_SHARED_LIBRARIES := \
     libEGL \
     libGLESv2 \
     libandroid \
     libandroidfw \
     libandroid_runtime \
     libchromium_net2 \
     libcrypto \
     libcutils \
     libdl \
     libgui \
     libicuuc \
     libicui18n \
     libmedia \
     libmedia_native \
     libnativehelper \
     libskia \
     libsqlite \
     libssl \
     libstlport \
     libutils \
     libui \
     libz
    static {
         System.load(“/data/local/libchromium_net2.so”);
         System.load(“/data/local/libwebcore2.so”);
    }

对此 Java 相关代码的调剂,那里大家第①行使 Android Studio
开发工具来拓展。

1.
调剂已运营的rild

导入源码到 Android Studio

要在 Android Studio 中调剂源码,那第2步自然是导入系统源码到 Android
Studio 中了。

对于 Android 源码的导入, 谷歌 官方给我们提供了三个很方便的工具
idegen

它身处大家所下载的类别源码路径中:

developement/tools/idegen

引用 README 的一句话

IDEGen automatically generates Android IDE configurations for IntelliJ
IDEAand Eclipse.

idegen 工具会自动生成针对 Android 开发工具(Android
Studio和Eclipse)的布置文件。

既是,那大家就来使用 idegen 工具生成导入源码所需的布署文件。

第3打开命令行工具,cd 进入到源码路径下,

进行如下指令:

#初始化命令工具soruce build/envsetup.sh #编译 idegen 模块,生成idegen.jarmmm development/tools/idegen/#生成针对 Android 开发工具的配置文件 sudo ./development/tools/idegen/idegen.sh

在执行完上述指令后,会在源码路径下生成上边八个文本

图片 2Paste_Image.png

android.ipr:工程有关的装置,比如编写翻译器配置、入口,相关的libraries等。

android.iml:描述了modules,比如modules的门路,正视关系等。

android.iws:包涵了一部分民用工作区的设置。

接下去大家能够起来导入源码了.

假若您是率先次导入源码, Android Studio
恐怕须要占用大量的内部存款和储蓄器,大家须要设置下大家的 VM 选项。

Linux 设备的话在 Android Studio 的 bin/studio64.vmoptions
文件中添加-Xms748m -Xmx748m

一经您使用的是 Mac ,那么在 AS 目录的 Contents/Info.plist
目录中举行添加。

由于 Android 的系统源码卓殊庞大,2遍性导入 Android Studio
的话须求加载非常长的大运

就此,在正式启幕导入前,我们得以打开 android.iml
文件根据本身需求调整要加载的源码。

图片 3Paste_Image.png

这里 <excludeFolder> 表示不须要加载的目录,大家依照本人的须要利用
<excludeFolder> 标签添加对应的目录地址即可。

接着,选择 File -> open 选中 android.ipr 文件,打开

图片 4Paste_Image.png

那儿 Android Studio 就会开头加载源码了

在并未添加修改 <excludeFolder>
的情状下,这几个加载的日子会相比长,经过一段时间的等候后,代码就加载达成了,如图:

图片 5Paste_Image.png

这边中灰的目录代表被 exclude 排除了,代码加载 scan index
的时候会过滤掉该目录。

在加载完源码后,大家也能够在 Project Structure 中的 Module 选项中右键
exclude 来解除不须要加载的源码目录,如图:

图片 6Paste_Image.png图片 7Paste_Image.png

为了阅读和调试代码的时候能够确定保证代码跳转正确,我们需求配置下相关重视。

率先是 AOSP 源码的跳转,大家经过 File -> Project Structure 打开
Module,然后选中 Dependencies, 保留 JDK 跟 Module Source
项,并添加源码的 external 和 frameworks 依赖,如图:

图片 8Paste_Image.png

下一场是 SDK 的装置,确认保证涉及对应版本的 SDK 于系统版本向来

图片 9Paste_Image.png

#ps | grep rild

千帆竞发调节和测试源码

调节前要设置 Project 的 SDK , File -> Project 下打开 Project
Structure,选中 Project 设置相应版本的 SDK,于系统版本一样:

图片 10Paste_Image.png

确保 Android Studio 允许 ADB 调试

图片 11Paste_Image.png

进而咱们参照上一篇文章中讲的章程打开 Android 模拟器

那时候点击 Android Studio 工具栏的 attach debugger to Android process
按钮,会打开 Choose Process
窗口,我们根据自身必要调剂的代码选拔相应的历程:

图片 12Paste_Image.png

那边假诺大家要调节 Android 自带浏览器的源码,如图,我们在它的进口文件
WebViewBrowserActivity 中的 loadUrlFromUrlBar 方法中打上断点。

图片 13Paste_Image.png

点击 WebViewBrowser 打开 app

图片 14Paste_Image.png

打开之后,点击 attach to Android process 按钮打开 choose
Process,能够看到 webViewBrowser 运营的经过,选中,ok

图片 15Paste_Image.png

下一场大家在 app 的 url 输入栏输入 网址举办跳转

图片 16Paste_Image.png图片 17Paste_Image.png

如图所示大家可以看到,代码成功进去了断点,然后大家就能够随心所欲地调节和测试大家想要的调剂的
Java 代码了。

对此 Framework Native 代码,大家这里运用 GDB 工具来拓展调节。

得到rild的进程rild-pid

什么是 GDB 呢?

它是一款 GNU 项目调节和测试工具,它的法力十三分有力,能够用来调节 C
、C++、Object-C、帕斯Carl 等语言编写的类型。

对此利用习惯了可视化 IDE
的同桌们的话,它最大的后天不足或者就是它不扶助图形化了

可是 GDB 提供的下令分外灵活,通过指令我们

  • 能够随心所欲地运转程序,
  • 可以依据本人的须求安装断点,
  • 能够查阅断点处的变量,代码音信
  • 能够查看程序运营的调用栈

假定您熟练了它,你便得以玩得飞起!

一般景色下,使用 gdb 来调节 Android 源码必要在 Android 设备上安装
gbdserver attach 关联大家必要调剂的长河,再利用 gdb 指令去老是 gdbserver
实行调节

可是官方给大家提供了 gdbclient 工具,可以让大家有益地开始展览 gdb 调节和测试。

#gdbserver :5039 --attach rild-pid

开始 GDB 调试

此地大家就依照 gdbclient 来开始展览实际的 gdb 调节和测试演示:

跟上边 Java 调节和测试一样,我们那里依旧以体系自带的浏览器为例。

图片 18Paste_Image.png

#进入源码路径cd aosp#初始化命令工具source build/envsetup.sh#选择编译的源码的版本,参考上一篇文章lunch

图片 19初叶化命令工具图片 20Paste_Image.png

# 通过 shell ps 指令查找相关进程,grep 搜索过滤 webview 进程adb shell ps -A | grep webview

图片 21Paste_Image.png

如图,2157 为系统自带浏览器 app 所在进度的 PID

# gdbclient <app pid> 可以启用 gdb 调试对应 PID 进程gdbclient 2157

图片 22Paste_Image.png

伺机进入 gdb 调节和测试命令界面

图片 23Paste_Image.png

在 gdb 指令中,大家选取b <代码文件>:行号 来设置断点.

此间我们采取 frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
代码文件的 drawFrame 方法打上断点,位于文件 71 行:

图片 24Paste_Image.png

该方法首要用以绘制帧,当浏览器 app 的界面发生变化时会触发该措施。

大家输入设置断点命令:

b frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp:71

图片 25Paste_Image.png

输入指令后出示Breakpoint 2 at 0x7f69e9892c11: file
frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp, line
71.表明大家的断点设置成功了。

图片 26Paste_Image.png

c 即 continue,此时界面上出现 Continuing 表明伊始监听进度了

小编们点开模拟器,随意操作,触发界面扭转时,便会跻身绘制帧的代码断点了:

图片 27Paste_Image.png

如图,展现进入断点,那样表示大家的代码调节和测试成功了。

此间大家只是演示了四个大体流程,

gdb 代码的调节供给你对源码有肯定的耳熟能详,知道哪些进程会调用哪个文件措施。

并且,大家还需求熟谙 gdb
的种种吩咐,那里给大家推荐一篇不错的入门小说,能够火速入门:

GDB十分钟教程

此地补充某个,假设你希望在某些进度运营时就监听,能够应用下边包车型地铁吩咐关联目录,得到pid,再通过 gdbclient 来进行调节

adb shell gdbserver :5039 /system/bin/my_test_appProcess my_test_app created; pid = 3460Listening on port 5039

gdbclient <app pid>

一旦您期望通过 Android Studio 来调节 Framework 的 C\C++
代码的话,也能够参见下边包车型大巴两篇作品,可是个人觉得那种措施有一定的局限性。

怎么着调节和测试Android Native Framework

用Android Studio调试Framework层代码

正如文章初始所说,唯有学会了什么样调节 Framework
源码,才能支援大家更好地球科学习 Android
Framework,希望这篇作品能给大家有些增派,假诺有更好地调试方法,欢迎大家给自个儿留言咯!

还是调试新的rild进度

#gdbserver :5039 rild

2.
用ADB设置转载端口

$adb forward tcp:5039 tcp:5039

3.
在android的platform目录下

$prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gdb
out/target/product/saarbmg1/symbols/system/bin/rild

4.
设置符号表

(gdb)set solib-absolute-prefix /home/loginname/android-platform/out/target/product/saarbmg1/symbols
(gdb)set solib-search-path /home/loginname/android-platform/out/target/product/saarbmg1/symbols/system/lib

5. 与GDB
server连接

(gdb)target remote :5039
(gdb)shared

末尾就足以拓展调节了

下边是常用的gdb调节和测试命令

(gdb)help [cmd]                            显示命令cmd的帮助
(gdb)bt                                    显示调用堆栈
(gdb)next|n                                执行下一代码
(gdb)step|s                                执行到下一行代码
(gdb)run|r                                 继续运行
(gdb)jump lineno                           执行到指定行为止
(gdb)break|b lineno|function if condifion  设置断点
(gdb)directory|dir dir1:dir2               指定源文件搜索路径

那正是说如何调节浏览器webkit等android应用的native代码呢?答案是毫无疑问的,作者成功单步调节和测试了webkit的代码。

相关文章