IT狗

用Android Studio调试Framework层代码

Android程式员不得不知的调试技能。
本文以webview loadUrl和域名分析为例,引见合营运用LLDB和Android Studio调试Framework代码的技能。

java 层调试

起首须要把AOSP源码导入到Android Studio中,假如是macOS零碎可以参考这篇美文
导入后以下图所示:

调试道理

Java平台的调试是有一个规范化的尺度的,那就是JPDA(Java Platform Debugger Architecture);经过 JPDA 供给的 API,开发职员可以利便机动的搭建 Java 调试应用程式。 JPDA 重要由三个部分组成:Java 假造机东西接口(JVMTI),Java 调试线和谈(JDWP),和 Java 调试接口(JDI)。
调试须要仓库、标记等信息都保管在JVM中,调试器(debugger)须要经过一种通道获得这些信息,并经过这个通道发送调试指令给JVM,JDWP就是调试器与JVM通讯的通道。在JVM内部有一个特意的jdwp线程,Android零碎的adbd保护进程经过socket与各个假造机的jdwp线程进行通讯,内部调试器经过主机的adb与adbd通讯进而完成与jdwp的通讯。详细进程以下图:
调试架构图

设置Debug选项

在菜单栏上顺次点击Run -> Edit Configurations -> Remote,翻开并设置成以下的页面
aosp_java_debug

Exclued 不必要的文件夹

在断点调试时,JVM会报告AS本身在xx.java的第xx行被断住了,AS就会定位到这个地位,可是假如有一次又一次的文件的名的,常常会呈现定位禁绝的状况,以是须要把不必要的文件夹清除在全部源码构造以外。翻开Project Structure,做以下修正
Exclued
假如遇上断点文件对不上的状况时,就手动在这里Exclued好了。
也可以间接修正aosp-root/development/tools/idegen/excluded-paths文件中的内容,增加exclude,再运转idegen.sh 从头天生IDE代码树。

在源码处打断点

咱们在WebView.java的loadUrl处打断点

点击调试按钮,你会发现Console中的提醒

1
Connected to the target VM, address: 'localhost:8700' , transport: 'socket'

翻开DDMS

在菜单栏上顺次点击Tools ->Android -> Android Device Monitor,翻开DDMS后,点击
ddms

在monitor中咱们可以发现有3列,辨别是

  • 进程名(以包名显现)
  • PID(Process ID)
  • 端标语(映照端标语/实践端标语)
    点击咱们要调试的browser程式的那一行,会呈现一只绿色的bug,暗示咱们的Debugger曾经跟装备上的程式接洽上,可以调试了。

开端调试

当在浏览器中加载一个网页时,就能触发之前设置的loadUrl的断点了,云云就可以运用种种调试手腕了。
loadUrl仓库


C++层调试

Android Framework中native代码的调试要领使用的是 2.2上述版本的Android Studio合营LLDB调试器。
这里以调试webview的dns查找进程为例,解释native调试的要领。

调试道理

LLDB作为Android Native层的调试东西,其道理跟gdb一样,也是使用C/S架构,经过push一个lldb-server到装备上,pc机的debugger作为lldb-client与其通讯,以到达调试的后果。
C++在编译时有一个选项-g暗示编译出来的可履行文件是带有调试信息的,比方源文件、行号信息,都会寄存在ELF文件中的
.debug_*段当中, 明白了这些调试信息后,调试器合营IDE就可以定位代码了。
这里还须要确保你的标记文件和装备上真正运转的静态链接库大概可履行文件是对应的,就是统一份,否则调试信息就对不上了。
最简洁的方法就是运用模拟器。咱们编译完源码以后,一个重要的编译产品就是 system.img,这个 system.img会在启动以后挂载到装备的 /system 分区,而system分区包罗了Android零碎运转时的绝大部分可履行文件和静态链接库,而这些文件就是咱们的编译输入,恰好可以与编译获得的调试标记进行合营调试。模拟器有一个 -system选项用来指定模拟器运用的 system.img文件。

1
$ emulator -avd Nexus5-API22 -verbose -no-boot-anim -system (the path of system.img)

我这里的方法是运用烧录了本身编译源码的Nexus手机。

设置Debugger

这里须要新建一个Android Demo项目了,间接用AOSP源码阿谁项目,没有是Native Debug阿谁选项的。
按以下方法设置标记表,须要与装备上用的so是统一份。并且改Debug type 为Native。
设置Debugger
标记表的增加也可以经过lldb下令行的方法增加
lldb-pause
lldb-add-dsym
LLDB须要这些标记信息能力帮你定位到调试断点的代码。

设置源码到AS

当LLDB报告AS源文件行号信息时,AS须要定位到对应的代码处,以是必需先把源文件导入到AS中,最简洁的方法是成立软链接。在Android Demo项目下成立一个source文件夹,然后履行以下下令。

1
2
$ ln -s xx/external/chromium_org xx/source/chromium_org
$ ln -s xx/bionic/libc xx/source/libc

这里只是把须要用到的源文件导入出去,固然也可以把全部AOSP源码导入AS中,可是这样会对比耗时。

打断点

我在getaddrinfo.c的getaddrinfo要领处打一个断点,看看webview在加载网页时的域名分析会不会走到这里。
getaddrinfo
点击Debug按钮,当Demo程式开端LoadUrl以后,就会被Debug断住,以下是chromium域名分析线程的仓库(这里的要领名真够长的。。。),这样咱们就可以进一步相识webview加载网页时域名分析的进程了。
getaddrinfo-stack
让咱们看看其他线程在干啥,全部天下都中止了。
chromium-threads
renderthread
jdwp


缺乏之处

现在的调试framework计划只能把java层和c++ native层的分隔来做,还不能够做到java层和c++ native层彼此跳转的后果。固然现在咱们开发Android App用AS调试时能做大这一点,要是framework的调试也能做到这一点就好了。获得真有这样的要领,假如有明白的大神,还请见教。


相干链接

Debugging AOSP Platform code with Android Studio - Part I - Java Debugger
Android Debugging: Old School bringup routines - Command line Java debugging with JDWP
怎样调试Android Framework
怎样调试Android Native Framework

在macOS 10.12 上编译 Android 5.1


转载: http://felixzhang00.github.io/2017/01/23/%E7%94%A8Android%20Studio%E8%B0%83%E8%AF%95Framework%E5%B1%82%E4%BB%A3%E7%A0%81/

此文由 IT狗 编辑,本网站所发布展示的作品/文章版权归原作者所有,任何商业用途均须联系作者!

相关推荐

评论 暂无评论