调试 Android* x86 应用程序的方法以及要使用的工具

作者:Xiaodong Wang

1.简单介绍

众所周知,Android* 开发者头顶很多称呼:设计员、程序员等,而且一般会不可避免地被称为故障检修工。

代码中的错误无法避免。因此不管您是否一開始就造成错误,了解调试工具以及怎样迅速而有效地跟踪并解决错误都非常重要。

鉴于此。现在的 Android 开发者必须掌握有效的调试技巧。

本文提供了 Android 应用程序调试工具的简单教学,用于帮助 Android SDK 以及相关工具的新手迅速入门。并在 Android x86 平台上更有效地解决故障。

2.SDK 应用程序调试工具

Android SDK 提供了试应用程序所需的大多数工具。

假设希望进行诸如单步调试代码、查看变量值以及暂停运行应用程序的操作,则须要兼容 JDWP 的调试程序。假设使用 Eclipse。则已附带兼容 JDWP 的调试程序,无需设置。假设使用其他 IDE,则可使用其附带的调试程序并将调试程序与特殊port连接,使其能够和您设备上的应用程序虚拟机通信。

假设使用 ADT(Android 开发工具)插件在 Eclipse 中进行开发,则可使用内置的 Java* 调试程序并结合 DDMS(Dalvik 调试监測程序server)来调试应用程序。

为了便于訪问调试程序和 DDMS。Eclipse 以视图形式显示调试程序和 DDMS 功能。这些都是自己定义的 Eclipse 视图。依据您所在的视图显示特定选项卡和窗体。Eclipse 还可负责为您启动ADB (Android Debug Bridge) 主机守护程序,从而无需手动执行该工具。假设使用其它 IDE 进行调试。则可使用 Android SDK 提供的全部调试工具,比如 ADB、DDMS、Java 调试程序等。

图 1. Dalvik 调试监測程序server

借助 DDMS,开发者可查看进程的堆区使用情况、跟踪对象的内存分配、使用模拟器或设备的文件系统、检查线程信息、获取方法配置、使用网络流量工具(在 Android 4.0 中提供)、使用 LogCat 跟踪代码信息以及模拟手机操作和位置。如欲了解很多其它信息,请參阅 http://developer.android.com/guide/developing/debugging/ddms.html。Android SDK 还提供 Hierarchy Viewer(层级观察器)和 layoutopt(布局优化分析工具)帮助开发者调试布局问题。

Hierarchy Viewer 应用程序可让您调试并优化您的用户界面 (UI)。它以可视方式呈现布局的视图层级(View Hierarchy 口),提供放大的显示视图(Pixel Perfect 窗体)。

图 2. Hierarchy Viewer(层级查看器)

View Hierarchy窗体显示形成您设备上或模拟器上执行的活动的 UI 的视图对象。

您能够用它在整个视图树的上下文中查看各个视图对象。对于每一个视图对象,View Hierarchy 窗体还显示渲染性能数据。在选择节点时。视图的额外信息出如今节点上方的小窗体中。 在单击当中一个节点时,可看到有关图像、视图计数和渲染时间的信息。

图 3. 查看对象信息窗体

Pixel Perfect 是一个工具。用于检查像素属性并通过设计图排布用户界面。

Pixel Perfect 窗体显示模拟器或设备上可见的屏幕的放大图像。在该窗体中。可检查屏幕图像中各个像素的属性。

也可使用 Pixel Perfect 窗体依据位图设计帮助排布应用程序的用户界面。

图 4. Pixel Perfect 窗体

layoutopt 工具可让您分析 XML 文件。该文件定义应用程序的用户界面以查找视图层级中的不当之处。

要执行工具,可打开终端并从 SDK 工具/文件夹启动 layoutopt <xmlfiles>。<xmlfiles> 变量是以空格分隔的要分析的资源的列表,能够是未编译的资源 xml 文件或这些文件的文件夹。

工具会载入指定的 XML 文件并依据一组提前定义的规则分析它们的定义和层级。 以下是来自工具的输出演示样例:

$ layoutopt samples/ samples/compound.xml 7:23 The root-level <FrameLayout/> can be replaced with <merge/> 11:21 This LinearLayout layout or its FrameLayout parent is useless samples/simple.xml 7:7 The root-level <FrameLayout/> can be replaced with <merge/> samples/too_deep.xml -1:-1 This layout has too many nested layouts: 13 levels, it should have <= 10! 20:81 This LinearLayout layout or its LinearLayout parent is useless 24:79 This LinearLayout layout or its LinearLayout parent is useless 28:77 This LinearLayout layout or its LinearLayout parent is useless 32:75 This LinearLayout layout or its LinearLayout parent is useless 36:73 This LinearLayout layout or its LinearLayout parent is useless 40:71 This LinearLayout layout or its LinearLayout parent is useless 44:69 This LinearLayout layout or its LinearLayout parent is useless 48:67 This LinearLayout layout or its LinearLayout parent is useless 52:65 This LinearLayout layout or its LinearLayout parent is useless 56:63 This LinearLayout layout or its LinearLayout parent is useless samples/too_many.xml 7:413 The root-level <FrameLayout/> can be replaced with <merge/> -1:-1 This layout has too many views: 81 views, it should have <= 80! samples/useless.xml 7:19 The root-level <FrameLayout/> can be replaced with <merge/> 11:17 This LinearLayout layout or its FrameLayout parent is useless

 

Traceview 是运行日志的图形化查看器。这些日志在您使用调试类记录代码中的跟踪信息时创建。Traceview 可帮助您调试应用程序并概述其性能。Traceview 可载入日志文件并在窗体中显示其数据,该窗体如图 5 和图 6 所看到的以两个面板将您的应用程序可视化:

 

图 5. 时间轴面板描写叙述每一个线程和方法何时開始和停止

图 6. Profile(概要)面板提供方法中花费的全部时间的摘要。

dmtracedump 是一种工具,为您提供一种备选方式,用于从跟踪日志文件生成图形调用栈图。

该工具使用 Graphviz Dot 有用程序创建图形化输出,因此您须要在执行 dmtracedump 之前安装 Graphviz。dmtracedump 工具以树图形式生成调用堆栈数据,每一个调用表示为一个节点。它使用箭头显示调用流程(从父节点至子节点)。图 7 显示了 dmtracedump 输出的一个演示样例。

图 7. dmtracedump

3.NDK 应用程序调试工具

因为 Android NDK 基于 GCC 工具链,Android NDK 包括 GDB、GNU 调试程序,因而可让您启动、暂停、检查和改动程序。在 Android 设备上,GDB 配置为client/server模式,在嵌入式设备上这样的配置更为常见。程序在设备上作为server和远程client执行。开发者的工作站与其连接,并发送与本地应用程序相似的调试命令。

GDB 本身是一个命令行有用程序,假设手动使用会显得较为繁琐。

幸好 GDB 可由大多数 IDE 尤其是 CDT 处理。

从而可直接使用 Eclipse 来加入断点并检查程序,但前提是先正确配置它!

通过单击文本编辑器的左端,Eclipse 确实可方便地用 Java 和 C/C++ 源文件插入断点。Java 断点借助 ADT 插件能够马上使用。该插件管理通过 Android Debug Bridge 进行的调试。但对 CDT 并不是如此,CDT 并不能感知 Android。

因此,插入断点将不会有作用。除非我们配置 CDT 以使用 NDK 的 GDB,GDB 本身须要绑定至原生应用程序以对其进行调试。

在 NDK 版本号中改善了对调试程序的支持(比如,之前不能调试纯原生线程)。虽然 NDK 越来越适用,但 NDK R5(甚至包含 R7)还非常不完好。可是,它仍然实用处。 如今让我们了解下怎样调试原生应用程序。

首先通过下面步骤在我们的应用程序中启用调试模式:
1)有一步操作非常重要。但也非常easy被忽略。那就是在 Android 项目中激活调试标记。该操作在应用程序清单 AndroidManifest.xml 中完毕。请勿忘记对原生代码使用适用的 SDK 版本号:

<?xml version="1.0" encoding="utf-8"?

> <manifest ...> <uses-sdk android:minSdkVersion="10"/> <application ... android:debuggable="true"> ...

 

2)在清单中启用调试标记会自己主动以原生代码激活调试模式。

可是,APP_OPTIM 标记也控制着调试模式。假设已在 Android.mk 中手动设置它,则检查是否已设置其值以进行调试(并不公布)或直接删除它:

APP_OPTIM := debug

 

 

3)如今让我们配置将连接至设备的 GDB client。又一次编译项目并插入设备或启动模拟器。

执行然后离开应用程序。确保载入应用程序而且其 PID 可用。

可通过使用下面命令(在 Windows 中使用 Cygwin)监听进程来检查它:

$ adb shell ps |grep gl2jni

 

 

应该会返回一行:

app_75 13178 1378 201108 68672 ffffffff 80118883 S com.android.gl2jni

 

 

4)打开终端窗体并转到项目文件夹。

执行 ndk-gdb 命令(位于 Android NDK 文件夹,比如 android-ndk-r8):

$ ndk-gdb

 

 

该命令不会返回消息,可是会在 objlocalx86 文件夹创建三个文件(对于 arm 设备文件夹为 objlocalarmeabi):

 

  • gdb.setup:这是为 GDB client生成的配置文件。

  • app_process:该文件直接从您的设备检索。其为系统可执行文件,在系统启动时启动,并可形成分支,启动新的应用程序。

    GBD 须要该參考文件来查找其标记。在某些方面,其为您的应用程序的二进制输入点。

  • libc.so:该文件也可直接从您的设备检索。其为 GDB 使用的 Android 标准 C 库(通常称为 bionic),用于保持跟踪执行时期间创建的全部原生线程。

5)在您的项目文件夹中,复制 objlocalx86gdb.setup 并将其命名为 gdb2.setup。打开它并删除请求 GDB client连接至执行于设备上的 GDB server的下面行(将由 Eclipse 自身执行):
target remote :5039

6在 Eclipse 主菜单中,转至“Run(执行)| Debug Configurations(调试配置)...”。并在名为 GL2JNIActivityDefault 的 C/C++ 应用程序项目中创建新的调试配置。

该配置将在您的计算机上启动 GDB client并连接至设备上执行的 GDB server。

7在 Main(主菜单)选项卡中。使用浏览button,将项目设置为自己的项目文件夹,将 C/C++ 应用程序设置为指向 objlocal x86app_process(能够使用绝对或相对路径)。

图 8. 为 C/C++ 应用程序调试配置

8使用窗体底部的链接“Select other(选择其它)...”。将启动程序类型切换为“Standard Create Process Launcher(标准创建进程启动程序)”:

图 9. 选择首选启动程序

9转至调试程序文件并设置调试程序类型为 gdbserver,将 GDB 调试程序设置为 android-ndk-r8 oolchainsx86-4.4.3prebuiltwindowsini686-android-linux-gdb.exe 或针对 arm 平台设置为 android-ndk-r8 oolchainsarm-linux-androideabi-4.4.3prebuiltlinux-x86inarm-linux-androideabi-gdb,针对 arm 平台将 GDB 命令文件需求设置为指向位于 objlocalx86 或 objlocalarmeabi 中的 gdb2.setup 文件(使用绝对或相对路径均可)。

图 10. 调试程序设置面板

10转至 Connection(连接)选项卡并将类型设置为 TCP。主机名、IP 地址和port号 (localhost d 5039) 都保留默认值。

图 11. 调试程序设置面板上的链接设置

11如今让我们配置 Eclipse 以在设备上执行 GDB server。

复制 android-ndk-r8 dk-gdb 并用文本编辑器打开它。查找下面行:
$GDBCLIENT -x `native_path $GDBSETUP`

因为 GDB client将由 Eclipse 本身执行,因此对其进行凝视:

#$GDBCLIENT -x `native_path $GDBSETUP`

12在 Eclipse 主菜单中,转到“Run(执行)| External Tools(外部工具)| External Tools Configurations(外部工具
配置)...”,并创建新配置 GL2JNIActivity_GDB。
该配置将在设备上启动 GDB server。

13在 Main(主菜单)选项卡上。将位置设置为指向 android-ndk-r8 中我们改动过的 ndk-gdb。 将工作文件夹设置为您的应用程序文件夹位置
也可设置 Arguments(变量)文本框:

  • Verbose:具体查看 Eclipse 控制台中发生了什么。
  • Force:自己主动终止之前全部会话。
  • start:让 GDB server启动应用程序,而不是在应用程序启动之后连接至应用程序。该选项在您仅调试原生代码而非 Java 代码时实用。

图 12. 外部工具配置

14如今。和往常一样启动应用程序。

15一旦应用程序启动,就可直接通过控制台启动 ndk-gdb 或启动外部工具配置 GL2JNIActivity_GDB。该配置将启动设备上的 GDB server。GDB server接收远程 GDB client发送的调试命令,并在本地调试您的应用程序。

16打开 jnigl_code.cpp 并通过双击文本编辑器的左端在 setupGraphics 中设置断点(或右键单击并选择 Toggle breakpoint(切换断点))。

图 13. 断点设置

17最后启动 GL2JNIActivity 默认 C/C++ 应用程序配置启动 GDB client。它会通过套接字连接将调试命令从 Eclipse CDT 中继至 GDB server。从开发者的观点来看,这与调试本地应用程序非常相似。

也有一些专用工具用于调试图形性能,比如 Intel® GPA System Analyzer 为英特尔® 图形性能分析器(英特尔® GPA)之中的一个,新添加了对于英特尔架构 Android 设备的支持,而且专供应用程序和驱动程序project师优化其 OpenGL* ES 工作量。

该部分提供的信息涉及怎样配置英特尔 GPA 并通过 USB 连接将其用于您的 Android 设备。在连接至 Android 设备时,英特尔 GPA System Analyzer 提供 OpenGL ES API、CPU 和 GPU 性能标准,并通过提供多个图形管线状态重写以帮助分析 OpenGL ES 应用程序性能。

要在基于 Android x86 的设备上使用英特尔 GPA System Analyzer,须要从文档检查目标机器和固件/版本号。

要開始收集标准,须要在client系统上安装英特尔 GPA System Analyzer 并将其连接至目标设备:

1在 Windows*/Linux* client机器上安装英特尔 GPA 2012 R3。

2启动英特尔 GPA System Analyzer。

3确保 Android 设备通过 USB 电缆连接至client系统。

4在client系统检測目标设备时。最多等待 10 秒。发现的设备会出如今对话框窗体中。目标设备的列表会每隔 5 到 6 秒刷新一次。

5查找要连接的设备并单击“Connect(连接)”。英特尔 GPA System Analyzer 会将所需的组件拷贝到目标设备并生成已安装应用程序的列表。可通过单击“Stop(停止)”中断连接进程。

图 14. 选择互联设备

6从可用应用程序列表中选择所需的应用程序。“Application List(应用程序列表)”屏幕显示全部用户以及 Android 设备上安装的全部系统应用程序。

图 15. 应用列表

7将会启动应用程序而且您将在英特尔 GPA System Analyzer 窗体中看到其数据。

8要切换至不同应用程序,单击“Back(返回)”。请注意,将强制关闭正在执行的应用程序。

9要切换至不同目标,单击“Back(返回)”。
PowerVR 显卡架构由下面核心模块构成。这些模块可将提交的 3D 应用程序数据转换为渲染的图形:Tile Accelerator (TA)、Image Synthesis Processor (ISP) 以及 Texture & Shading Processor (TSP)。“GPU” 组中的英特尔 GPA 标准相应这些核心模块之中的一个,“Metrics List(标准列表)”中标准的顺序取决于图形管线中核心模块的顺序。

图 16. Intel GPA System Analyzer 窗体

Perf 是自 Linux 版本号 2.6.30 起 Linux 中非常实用的一个工具。可同一时候用于与硬件和软件相关的性能分析。虽然 Android 基于 Linux 构建,但和不包括其它 Linux 组件和库一样。它也不包括 perf。您必须将静态构建的 perf 推送至当中。假设您已有该工具,仅仅需将其置于 /system/bin/ 下。就可有效发挥其作用。

有关 perf 的简短说明、基本使用方法和教程。可訪问https://perf.wiki.kernel.org/index.php/Main_Page
借助 traceview,开发者可获取 Java 代码的性能信息。借助 perf。开发者可获取有关原生和系统级代码的性能信息,如图 17 中所看到的。

图 17. 性能统计数据

图 18. 函数调用栈

UxTune 是一个project工具,用于 Android 用户交互分析和优化。它是一种增强的 pyTimeChart 工具。


UxTune 设计特性包含:

  • 垂直相关:将跨层的系统事件映射至用户级别活动,比如事件、手势、帧等。
  • 水平相关:将不同系统实体间的执行时活动(比如一个线程触发垃圾回收)关联。

  • 基于 pyTimeChart 的可视化。

要使用 UxTune 分析响应能力,开发者须要熟悉 Android 系统的某些重要进程(在 pyTimeChart 中显示为行)。即:

  1. InputReader 行:该行以触摸坐标显示全部触摸事件。事件将发送至 InputDispatcher。
  2. InputDispatcher 行:InputDispatcher 将把连续的触摸事件打包,并将该包发送至应用程序的 uiThread。
  3. uiThread 行:该行显示从 InputDispatcher 收到的包的主要触摸事件。uiThread 将依据特定操作绘制(渲染)其表面。 “D” 表示绘制进程。
  4. Surface 行:uiThread 在绘制開始时锁定其表面,并在绘制完毕后解锁表面。“S” 和 “E” 表示应用程序渲染的開始和结束。
  5. SurfaceFlinger 行:在完毕应用程序渲染后,应用程序将通知 SurfaceFlinger 合成并更新屏幕。“S” 表示 SurfaceFlinger 開始处理应用程序请求,而 “E” 表示合成完毕(帧缓冲区交换完毕)。

图 19. UxTune 分析窗体

Meter-FPS 是一个工具,用于測量系统的 FPS 值。它会截取显卡处理路径以获得每帧的记录,还包括其它标准。比如最大帧时间、帧时间变化、#长时帧和掉帧率。fps 监控器有两种模式。Real Time Pattern(实时模式)可实时显示全部正在执行的应用程序的 fps。Measure Pattern(測量模式)可在用户定义的启动和停止时间測量 fps 和其它參数。要使用该工具。必须取得设备最高权限。
设置环境:
setprop debug.graphic_log 1
stop zygote
start zygote

图 20 显示了配置界面,开发者可在当中为调试目标配置工具。

20. Meter-FPS 配置

在 Real Time(实时)模式中单击监控器button。fps 工具将监控全部正在执行的应用程序,并在屏幕上的浮动窗体中更新 fps。

图 21. Meter-FPS 实时模式

在 Measure(測量)模式中单击监控器button。

将显示一个浮动窗体。当中显示“Click to start(单击以開始)...”;单击浮动窗体開始监控。

图 22. Meter-FPS 实时模式 1

如今測量模式正在执行:

图 23. Meter-FPS 实时模式 1

单击浮动窗体停止监控;其将显示结果:

图 24. Meter-FPS 分析结果列表

单击上面列表中的每一个项目以获取具体记录:

图 25. Meter-FPS 分析具体记录

參考:

http://developer.android.com/guide/developing/debugging/index.html
http://www.eclipse.org/sequoyah/documentation/native_debug.php
http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-development/
http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-debugging/
http://packages.python.org/pytimechart/userguide.html
https://perf.wiki.kernel.org/index.php/Main_Page

相关文章与资源:

关于作者

Xiaodong Wang 是英特尔软件及服务事业部的应用project师。

他专注于採用 Android 操作系统的基于英特尔的平台的 ISV。 Xiaodong 提供技术支持的 PRC Plus 项目(Android 平板电脑 ISV 启用)成功启用了前 50 个 NDK 应用程序作为技术接口。近期 Xiaodong 參与了英特尔的数个创新项目,并在开发过程中扮演重要角色。

尤其是当中一个项目被选为英特尔信息技术峰会的演示项目,而 Xiaodong 成功地提供了技术支持。

在增加英特尔之前,Xiaodong 在 MediaTek 进行有关框架和应用程序开发的工作。Xiaodong 是北京大学硕士。并在作为訪问学者在新加坡南洋大学进行研究期间,在《IEEE 计算机汇刊》上发表了一篇技术论文。他感兴趣的领域为移动互联网技术(比如 LBS、NFC AR 等)以及创新设计。

 

声明

 

本文件里包含关于英特尔产品的信息。本文件不构成对不论什么知识产权的授权,包含明示的、暗示的。也不管是基于禁止反言的原则或其它。英特尔不承担不论什么其它责任。

英特尔在此作出免责声明:本文件不构成英特尔关于其产品的使用和/或销售的不论什么明示或暗示的保证,包含不就其产品的(i)对某一特定用途的适用性、(ii)适销性以及(iii)对不论什么专利、版权或其它知识产权的侵害的承担不论什么责任或作出不论什么担保。

除非经过英特尔的书面允许认可。英特尔的产品无意被设计用于或被用于下面应用:即在这种应用中可因英特尔产品的故障而导致人身伤亡。

英特尔有权随时更改产品的规格和描写叙述,恕不另行通知。

设计者不应信赖不论什么英特产品所不具有的特性,设计者亦不应信赖不论什么标有保留权利摂或没有定义摂说明或特性描写叙述。

对此。英特尔保留将来对其进行定义的权利。同一时候。英特尔不应为因其日后更改该等说明或特性描写叙述而产生的冲突和不相容承担不论什么责任。此处提供的信息可随时更改,恕不另行通知。请勿依据本文件提供的信息完毕一项产品设计。

本文件所描写叙述的产品可能包括使其与宣称的规格不符的设计缺陷或失误。这些缺陷或失误已收录于勘误表中。可索取获得。

在发出订单之前,请联系当地的英特尔营业部或分销商以获取最新的产品规格。

如欲获得本文涉及的带编号文档的副本或其它英特尔文献。可致电 1-800-548-4725,或訪问:http://www.intel.com/design/literature.htm
性能測试中使用的软件和工作负载可能仅在英特尔® 微处理器上针对性能进行了优化。诸如SYSmark和MobileMark等測试均系基于特定计算机系统、硬件、软件、操作系统及功能。上述不论什么要素的变动都有可能导致測试结果的变化。

请參考其它信息及性能測试(包含结合其它产品使用时的执行性能)以对目标产品进行全面评估。


对本文件里包括的软件源码的提供均根据相关软件许可而做出,不论什么对该等源码的使用和复制均应依照相关软件许可的条款运行。

英特尔和 Intel 标识是英特尔在美国和/或其它国家的商标。
英特尔公司 © 2012 年版权全部。

全部权保留。


* 其它的名称和品牌可能是其它全部者的资产。


原文地址:https://www.cnblogs.com/yutingliuyl/p/6845105.html