android 的调试工具集

#移动开发 #Android

1. 查看当前堆栈

  1. 功能:在程序中加入代码,使可以在 logcat 中看到打印出的当前函数调用关系

  2. 方法:

1
new Exception(“print trace”).printStackTrace();

2. MethodTracing

  1. 功能:用于热点分析和性能优化,分析每个函数占用的 CPU 时间,调用次数,函数调用关系等

  2. 方法:

  1. 在程序代码中加入追踪开关
1
2
3
4
5
6
import android.os.Debug;  
……
android.os.Debug.startMethodTracing(“/data/tmp/test”); // _ _ 先建 _ _
/data/tmp _ _ 目录 _ _
…… // _ _ 被追踪的程序段 _ _
android.os.Debug.stopMethodTracing(); _
  1. 编译,运行后,设备端生成 /data/tmp/test.trace 文件

  2. 把 trace 文件复制到 PC 端

1
$ adb pull /data/tmp/test.trace ./  _
  1. 使用 android 自带工具分析 trace 文件
1
$ $ANDROID_SRC/out/host/linux-x86/bin/traceview test.trace  _  

此时可看到各个函数被调用的次数 CPU 占用率等信息

  1. 使用 android 自带工具分析生成调用关系类图
1
2
$ apt-get install graphviz #  _ _ 安装图片相关软件  _ _  
$ANDROID_SRC/out/host/linux-x86/bin/dmtracedump -g test.png test.trace

此时目录下生成类图 test.png

  1. 注意
    trace 文件生成与 libdvm 模块 DEBUG 版本相冲突,所以此方法只适用于对非 DEBUG 版本模拟器的调试,否则在分析

trace 文件时会报错

3. HProf (Heap Profile)

  1. 功能: 用于 java 层面的内存分析,显示详细的内存占用信息,指出可疑的内存泄漏对象

  2. 方法:

  1. 在代码中加入 dump 动作
1
2
3
4
5
6
7
8
import android.os.Debug;  
import java.io.IOException;
……
try {
android.os.Debug.dumpHprofData(“/data/tmp/input.hprof”); // _ _ 先建 _ _
/data/tmp _ _ 目录 _ _
} catch (IOException ioe) {
}
  1. 把 hprof 文件复制到 PC 端
    _ $ adb pull /data/tmp/input.hprof./ _

  2. 使用命令 hprof-conv 把 hprof 转成 MAT 识别的标准的 hprof
    _ $ $ANDROID_SRC/out/host/linux-x86/bin/hprof-conv input.hprof output.hprof _

  3. 使用MAT工具看 hprof 信息
    下载 MAT 工具:[http://www.eclipse.org/mat/downloads.php

](http://www.eclipse.org/mat/downloads.php)
用工具打开 output.hprof

  1. 注意:此工具只能显示 java 层面的,而不能显示C层的内存占用信息

4. SamplingProfile (android 2.0 上版本使用)

  1. 功能
    每隔N毫秒对当前正在运行的函数取样,并输出到 log 中

  2. 在代码中加入取样设定

1
2
3
4
5
6
7
import dalvik.system.SamplingProfiler  
……
SamplingProfile sp = SamplingProfiler.getInstance();
sp.start(n); // n _ _ 为设定每秒采样次数 _ _
sp.logSnapshot(sp.snapshot());
……
sp.shutDown(); _

它会启一个线程监测,在 logcat 中打印信息

5. 用发系统信号的方式取当前堆栈情况和内存信息

  1. 原理
    dalvik 虚拟机对 SIGQUIT 和 SIGUSR1 信号进行处理 (dalvik/vm/SignalCatcher.c)

,分别完成取当前堆栈和取当前内存情况的功能

  1. 用法
1
2
3
4
5
6
7
8
$ chmod 777 /data/anr -R #  _ _ 把  _ _ anr  _ _ 目录权限设为可写  _ _  
$ rm /data/anr/traces.txt # _ _ 删除之前的 _ _ trace _ _ 信息 _ _
$ ps # _ _ 找到进程号 _ _
$ kill -3 _ _ 进程号 _ _ # _ _ 发送 _ _ SIGQUIT _ _ 信号给该进程,此时生成 _ _ trace _
_ 信息 _ _
$ cat /data/anr/traces.txt _
功能实现:遍历 thread list(dalvik/vm/Thread.c:dvmDumpAllThreadEx()) ,并打印当前函数调用关系
(dalvik/vm/interp/Stack.c:dumpFrames())
1
$ chmod 777 /data/misc -R 

$ ps # _ _ 找到进程号 _ _
$ kill -10 _ _ 进程号 _ _ # _ _ 发送 _ _ SIGQUIT _ _ 信事信号给该进程,此时生成 _ _ hprof

_ _ 信息 _ _
$ ls /data/misc/*.hprof _

1
2
3
4
5
6
7
8
9
10
11
12
13
此时生成  hprf  文件,如何使用此文件,见第二部分  (HProf)  
注意: hprof 文件都很大,注意用完马上删除,以免占满存储器

6\. logcat 及原理

1) android.util.Log 利用 println 的标准 java 输出词句,并加前缀 I/V/D….

2) dalvik 利用管道加线程的方式,先利用 dup2 把 stdout 和 stderr 重定向到管理中
(vm/StdioConverter.c:dvmstdioConverterStartup) ,然后再启动一个线程从管道另一端读出内容
(dalvik/vm/StdioConverter.c:stdioconverterThreadStart()) ,使用 LOG 公共工具(
system/core/liblog/logd_write.c: __android_log_print() )输出到 /dev/log/* 中去

3) logcat 通过加不同参数看 /dev/log/ 下的不同输入信息

logcat -b main _ _ 显示主缓冲区中的信息 _ _

logcat -b radio _ _ 显示无线缓冲区中的信息 _ _

logcat -b events _ _ 显示事件缓冲区中的信息 _

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

7\. jdwp(java debug wire protocol) 及原理

1) 虚拟机(设备端)在启动时加载了 Agent JDWP 从而具备了调试功能。在调试器端( PC 端)通过 JDWP
协议与设备连接,通过发送命令来获取的状态和控制 Java 程序的执行。 JDWP 是通过命令( command )和回复( reply
)进行通信的。

2) JDK 中调试工具 jdb 就是一个调试器, DDMS 也提供调试器与设备相连。

3) dalvik 为 JDWP 提供了两种连接方式: tcp 方式和 adb 方式, tcp 方式可以手工指定端口, adb
方式自动设定为 8700 端口,通常使用 DDMS 调试就是通过 adb 方式

8\. monkey

1) monkey 是一个 android 自带的命令行工具。它向系统发送伪随机的用户事件流,实现对正在开发的应用程序进行压力测试。

2) 方法
在设备端打开 setting 界面

$ adb shell

monkey -p com.android.settings -v 500

1
2
3
4
5
6
此时可以看到界面不断被切换

9\. 其它小工具
具体见 android.os.Debug 中提供的工具

1) 取毫微秒级的时间,用于计算时间

threadCpuTimeNanos()

1
2

2) 统计两点间的内存分配情况

startAllocCounting()
stopAllocCounting()
getGlobalAllocCount()
get…..

1
2

3) 打印当前已 load 的 class

_ getLoadedClassCount()
printLoadedClasses() _ _ 它需要打开 _ _ NDEBUG _ _ 功能才能打开 _ _ system/core/ _ _

中 _ _ Log _ _ 功能 _

1
10\.  打印  debug  信息  

_ $ adb bugreport _

```

11. 参考

  1. android 中 monkey 的用法
    http://junjie0324.spaces.live.com/blog/cns!BAAE46DF931F8C64!204.entry

(转载请注明出处: http://xy0811.spaces.live.com )