三九宝宝网宝宝教育学龄段教育

如何分析Android的Log

02月09日 编辑 39baobao.com

[电力系统短路分析]1、潮流计算,研究电力系统稳态运行情况的一种基本电气计算,常规潮流计算的任务是根据给定的运行条件和网路结构确定整个系统的运行状态,如各母线上的电压(幅值及相角)、网络中的...+阅读

首先,让我们看一看AndroidLog的格式。下面这段log是以所谓的long格式打印出来的。从前面Logcat的介绍中可以知道,long格式会把时间,标签等作为单独的一行显示。[ 12-09 21:39:35.510 396: 416 I/ActivityManager ]Start procnet.coollet.infzmreader:umengService_v1 for servicenet.coollet.infzmreader/com.umeng.message.UmengService:pid=21745 uid=10039 gids={50039, 3003, 1015,1028}[ 12-09 21:39:35.518 21745:21745I/dalvikvm ]Turning on JNI app bug workarounds fortarget SDK version 8...[ 12-09 21:39:35.611 21745:21745D/AgooService ]onCreate()我们以第一行为例:12-09 是日期,21:39:35.510是时间396是进程号,416是线程号;I代表log优先级,ActivityManager是log标签。

在应用开发中,这些信息的作用可能不是很大。但是在系统开发中,这些都是很重要的辅助信息。开发工程师分析的log很多都是由测试工程师抓取的,所以可能有些log根本就不是当时出错的log。如果出现这种情况,无论你怎么分析都不太可能得出正确的结论。如何能最大限度的避免这种情况呢?笔者就要求测试工程师报bug时必须填上bug发生的时间。

这样结合log里的时间戳信息就能大致判断是否是发生错误时的log。而且根据测试工程师提供的bug发生时间点,开发工程师可以在长长的log信息中快速的定位错误的位置,缩小分析的范围。同时我们也要注意,时间信息在log分析中可能被错误的使用。例如:在分析多线程相关的问题时,我们有时需要根据两段不同线程中log语句执行的先后顺序来判断错误发生的原因,但是我们不能以两段log在log文件中出现的先后做为判断的条件,这是因为在小段时间内两个线程输出log的先后是随机的,log打印的先后顺序并不完全等同于执行的顺序。

那么我们是否能以log的时间戳来判断呢?同样是不可以,因为这个时间戳实际上是系统打印输出log时的时间,并不是调用log函数时的时间。遇到这种情况唯一的办法是在输出log前,调用系统时间函数获取当时时间,然后再通过log信息打印输出。这样虽然麻烦一点,但是只有这样取得的时间才是可靠的,才能做为我们判断的依据。另外一种误用log中时间戳的情况是用它来分析程序的性能。

一个有多年工作经验的工程师拿着他的性能分析结果给笔者看,但是笔者对这份和实际情况相差很远的报告表示怀疑,于是询问这位工程师是如何得出结论的。他的回答让笔者很惊讶,他计算所采用的数据就是log信息前面的时间戳。前面我们已经讲过,log前面时间戳和调用log函数的时间并不相同,这是由于系统缓冲log信息引起的,而且这两个时间的时间差并不固定。

所以用log信息前附带的时间戳来计算两段log间代码的性能会有比较大的误差。正确的方法还是上面提到的:在程序中获取系统时间然后打印输出,利用我们打印的时间来计算所花费的时间。了解了时间,我们再谈谈进程Id和线程Id,它们也是分析log时很重要的依据。我们看到的log文件,不同进程的log信息实际上是混杂在一起输出的,这给我们分析log带来了很大的麻烦。

有时即使是一个函数内的两条相邻的log,也会出现不同进程的log交替输出的情况,也就是A进程的第一条log后面跟着的是B进程的第二条log,对于这样的组合如果不细心分析,就很容易得出错误的结论。这时一定要仔细看log前面的进程Id,把相同Id的log放到一起看。不同进程的log有这样的问题,不同的线程输出的log当然也存在着相同的问题。Logcat加上-vthread就能打印出线程Id。

但是有一点也要引起注意,就是Android的线程Id和我们平时所讲的Linux线程Id并不完全等同。首先,在Android系统中,C++层使用的Linux获取线程Id的函数gettid()是不能得到线程Id的,调用gettid()实际上返回的是进程Id。作为替代,我们可以调用pthread_self()得到一个唯一的值来标示当前的native线程。Android也提供了一个函数androidGetThreaId()来获取线程Id,这个函数实际上就是在调用pthread_self函数。

但是在Java层线程Id又是另外一个值,Java层的线程Id是通过调用Thread的getId方法得到的,这个方法的返回值实际上来自Android在每个进程的java层中维护的一个全局变量,所以这个值和C++层所获得的值并不相同。这也是我们分析log时要注意的问题,如果是Java层线程Id,一般值会比较小,几百左右;如果是C++层的线程,值会比较大。在前里面的log样本中,就能很容易的看出,第一条log是Jave层输出的log,第二条是native层输出的。

明白了这些,我们在分析log时就不要看见两段log前面的线程Id不相同就得出是两个不同线程log的简单结论,还要注意Jave层和native层的区别,这样才能防止被误导。AndroidLog的优先级在打印输出时会被转换成V,I,D,W,E等简单的字符标记。在做系统log分析时,我们很难把一个log文件从头看到尾,都是利用搜索工具来查找出错的标记。比如搜索“E/”来看看有没有指示错误的log。

所以如果参与系统开发的每个工程师都能遵守Android定义的优先级含义来输出log,这会让我们繁重的log分析工作变得相对轻松些。Android比较常见的严重问题有两大类...

以下为关联文档:

电力系统短路故障分析第一问题借用已有答案:不对称故障会产生负序电流和电压。而不对称接地故障或断线故障会产生零序电压,是否产生零序电流取决于系统的接地运行方式。 负序电流流过定子绕组在气...

如何用matlab实现无限大功率电源供电系统的三相短路分析暂态上机计算教学指导书(适用于Matlab) 一、基础知识1. 为完成本次设计,需要掌握的Matlab的基础知识有:数组的创建和计算,循环语句,条件选择语句,条件判断语句,绘制二维图的语句;2....

在混联电路中怎样分析局部短路的原因或整体短路原因以一相对地的短路故障最多,约占全部故障的90%,用导线或开关直接将某电路元件或负载的两端连接起来。(这是因需要并不会导致因电流过大而发生烧毁现象的安全连接。电气线路上,其...

我想请教下小米2是买个工程机好呢还是等正式板的好谁给我分析所谓手机工程机就是新机型在手机下线之前,都要出用于测试用的机器。主要是测试版本和硬件是否符合标准等。主要使用范围在公司内部及一些手机爱好者或是发烧用户,一般情况下是...

如何用excel做回归分析以Excel2010为例。 1、“开发工具”选项卡 中单击“加载项”组中的“加载项”按钮,打开“加载宏”对话框。如下图。勾选 “分析工具库”。 2、“数据”选项卡中“分析”组中...

用excel怎么做数据分析回归方法/步骤 打开Excel.2010,首先输入课本例题7.1的全部数据,2012年各地区农村居民家庭人均纯收入与人均消费支出, 做题之前,我们先为Excel.2010注入回归分析的相关内容,点击【文件...

假如你要开一家奶茶店你会怎么选地址并分析一下需求市场目前,奶茶店的消费市场是比较好的,这成为很多小本创业者的优质项目,对于创业者来说,确定好了合作项目,选址就成为开店的重中之重了,很多人创业者在选址上可谓是煞费苦心,他们不知道...

西数移动硬盘故障求分析如果硬盘原因导致电脑蓝屏,按照“先软后硬”的原则,一般可以采用硬盘修复或更换新硬盘的办法进行解决。 硬盘修复是通过软件对硬盘进行修复。这类修复软件包括:系统自带的硬盘...

页面调度算法的实现和分析源码dev c++ #include#include#includetypedef struct mem { int num; int v; }meme; static int process[1024],L,M; void LRU(); void FIFO(); void get(); int menu(); int m...

推荐阅读
图文推荐