5AndroidLog大全.docx
《5AndroidLog大全.docx》由会员分享,可在线阅读,更多相关《5AndroidLog大全.docx(17页珍藏版)》请在冰点文库上搜索。
5AndroidLog大全
Androidlog系统
Android系统log抓取,实现原理分析
一概述
本文档主要是供Android开发人员使用,特别是Framework开发。
因为Framework中95%以上的问题都是靠分析log解决的,所以开发人员必须对android整个log系统十分清楚。
什么问题抓什么log,使用什么工具抓Log,如何分析log,如何在代码中添加log.
二DDMSlog
关于ddms是如何工作的和ddms的详细功能,见下面androidsdk中文档详细介绍:
F:
\02Android\01_SDK\Gingerbread2.3\docs-2.3_r01-linux\guide\developing\tools\ddms.html
Ddms工具中打印log的几个菜单如下:
Device->Showprocessstatus…
Device->Dumpdevicestate…
Device->Dumpappstate…
Device->Dumpradiostate…
Device->Runlogcat…
1、Showprocessstatus…菜单
等效于在adbshell下执行adbshellps–x命令,该命令打印出进程的详细信息,如下:
USERPIDPPIDVSIZERSSWCHANPCNAME
root10268180c009b74c 0000875c S/init(u:
2,s:
371)
root2000c004e72c 00000000 Skthreadd(u:
0,s:
1)
root3200c003fdc8 00000000 Sksoftirqd/0(u:
0,s:
0)
root4200c004b2c4 00000000 Sevents/0(u:
0,s:
39)
root5200c004b2c4 00000000 Skhelper(u:
0,s:
0)
root6200c004b2c4 00000000 Ssuspend(u:
0,s:
0)
USER用户名,即用户所在组
PID进程ID(ProcessID)
PPID父进程的进程ID(ParentProcessid)
VSZ进程所使用的虚拟内存的大小(VirtualSize)
RSS进程使用的驻留集大小或者是实际内存的大小,Kbytes字节。
WCHAN进程正在睡眠的内核函数名称;该函数的名称是从/root/system.map文件中获得的
ExploringProcesses
Youcanseetheoutputofps-xforaspecificVMbyselectingDevice>Showprocessstatus...inthemenubar.
2、Dumpdevicestate…菜单
等效于执行/system/bin/dumpstate /proc/self/fd/0
等效于执行adbshelldumpstate命令
TorundumpstatefromDalvik,selectDevice>Dumpdevicestate...inthemenubar.
3、Dumpappstate…菜单
等效于执行adbshelldumpsys命令
输出android服务状态信息,即输出服务中dump函数的log.
4、Dumpradiostate…菜单
等效于执行adbshellcat/data/logs/radio命令
ExamineRadioState
Bydefault,radiostateisnotoutputduringastandardlogcat(itisalotofinformation).Toseeradioinformation,eitherclickDevice>Dumpradiostate...orrunlogcatasdescribedinLoggingRadioInformation.
5、Runlogcat…菜单
等效于执行adblogcat
Torundumpsys(logcat)fromDalvik,selectDevice>Runlogcat...inthemenubar.
总结:
除了Runlogcat…菜单是实时输出设备中的log外,其他菜单都是输出设备中缓存的log
三AdbLog
Androidsdk文档中对adb的介绍见下:
F:
\02Android\01_SDK\Gingerbread2.3\docs-2.3_r01-linux\guide\developing\tools\adb.html
在adb1.0.26版本共有2条命令打印log,如下:
adblogcat[]-Viewdevicelog
adbbugreport-returnallinformationfromthedevice
thatshouldbeincludedinabugreport.
Adblogcat常用命令
logcat-c清除已有log信息
logcat-bmain显示主缓冲区的log
logcat-bradio显示无线缓冲区的log
logcat-bevents显示事件缓冲区的log
logcat-f[filename]将log保存到指定的文件中,例如logcat-bradio-f/data/radio.log
比较常用的是显示时间:
logcat-vtime&
logcat-g查看缓冲区的大小
logcat-gmain
logcat-gradio
logcat-gevents
logcat打印/dev/log设备下的三个文件radio,events,main数据
logcat默认是输出main缓冲区的log
控制日志输出格式
日志信息包括了许多元数据域包括标签和优先级。
可以修改日志的输出格式,所以可以显示出特定的元数据域。
可以通过-v选项得到格式化输出日志的相关信息.
brief—Displaypriority/tagandPIDoforiginatingprocess(thedefaultformat).
process—DisplayPIDonly.
tag—Displaythepriority/tagonly.
thread—Displayprocess:
threadandpriority/tagonly.
raw—Displaytherawlogmessage,withnoothermetadatafields.
time—Displaythedate,invocationtime,priority/tag,andPIDoftheoriginatingprocess.
long—Displayallmetadatafieldsandseparatemessageswithablanklines.
当启动了logcat,你可以通过-v选项来指定输出格式:
[adb]logcat[-v]
此外,adbshellcmd,cmd为/system/bin目录下抓log的可执行程序,如dumpsys,dumpstate等
Adb下的log命令:
Adblogcat
Adbbugreport
Adbshelldumpsys
Adbshelldumpstate
Adbshelldmesg//导出当前缓存的kernellog
Adbshellkmsgcat//实时查看kernellog
其他查看系统当前信息命令
Adbshellps//查看系统进程信息,可以加很多有用信息
Adbshellpm//查看package相关信息
Adbshellam//启动apk应用
Adbshellsetprop//设置系统属性
Adbshellgetprop//查看所有系统属性
Adbshellreboot
Adbshellkill//通过进程ID杀死指定的进程
Adbshelltop//查看当前运行进程信息
Adbshellvmstat//查看虚拟机信息
Adbshellbootanimation//播放开机动画
Adbshelldf//查看分区信息
Adbshellmonkey//跑自动化测试用例
四保存在手机的Log
1、手机dropbox默认路径:
/data/system/dropbox/
实现机制:
log文件什么场景产生?
Log文件分析:
2、手机anr日志默认路径:
/data/anr/
实现机制:
log文件什么场景产生?
Log文件分析:
4、tombstones路径:
/data/tombstones
log文件什么场景产生?
Log文件分析:
五如何实现后台抓Log
如:
adblogcat-vtime-r1024-n16-f/sdcard/bugreports/applogcat-log
六log执行程序实现机制
1、Logcat
LogCat是在文件system/core/logcat/logcat.cpp中实现的。
从Logger设备驱动的实现知道,Log的读取是阻塞的操作,亦即,有数据可用,读出数据;否则,读操作会被BLOCK,相应的读进程也会被挂起等待。
下面看应用程序LogCat中如何实现读的,这可能需要不断回头与写操作和驱动实现结合来看。
看具体实现之前,先看一个logcat中定义的重要的结构体log_device_t。
其中的重要的成员在后面用到的时候再具体解释。
Android的Logcat命令详解的命令参数-b知道,logcat是可以通过参数来指定对哪个buffer(main/radio/event)进行操作的。
Logcat的b参数解析的地方,是通过传递进来的参数(main/radio/event)来创建了一个上面的结构变量,而这些结构通过log_device_t.next链接起来
因为logcat可能会同时操作多个Buffer,而read()会阻塞读取进程,对其他Buffer的读取就不能进行,所以这里用select()来判断可读取的Buffer。
2、Bugreport
I:
\00_AndriodSource\android-gingerbread-src\frameworks\base\cmds\bugreport
#include
#include
intmain(intargc,char*argv[]){
charbuffer[65536];
inti,s;
/*startthedumpstateservice*/
property_set("ctl.start","dumpstate");//启动dumpstate服务
/*socketwillnotbeavailableuntilservicestarts*/
for(i=0;i<10;i++){
s=socket_local_client("dumpstate",
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
if(s>=0)
break;
/*tryagainin1second*/
sleep
(1);
}
if(s<0){
fprintf(stderr,"Failedtoconnecttodumpstateservice\n");
exit
(1);
}
while
(1){
intlength=read(s,buffer,sizeof(buffer));
if(length<=0)
break;
fwrite(buffer,1,length,stdout);
}
close(s);
return0;
}
原理:
启动dumpstate服务,通过socket连接dumpstate服务,然后从socket中不断读取dumpstate侧的log打印出来
通过代码分析和实际对比分析,发现bugreport输出的log和dumpstate输出的log完全一致。
3、Dumpstate
I:
\00_AndriodSource\android-gingerbread-src\frameworks\base\cmds\dumpstate
输出的信息包括:
1、版本信息
2、系统状态信息:
CPU内存进程系统属性等
3、Logcat信息
4、Dumpsys输出的所以services信息
5、ANRlog信息
6、Dmesgkernellog信息
会运行下面命令输出log
run_command("CPUINFO",10,"top","-n","1","-d","1","-m","30","-t",NULL);
run_command("PROCRANK",20,"procrank",NULL);
run_command("SYSTEMLOG",20,"logcat","-v","time","-d","*:
v",NULL);
run_command("EVENTLOG",20,"logcat","-b","events","-v","time","-d","*:
v",NULL);
run_command("RADIOLOG",20,"logcat","-b","radio","-v","time","-d","*:
v",NULL);
run_command("NETWORKINTERFACES",10,"netcfg",NULL);
run_command("KERNELLOG",20,"dmesg",NULL);
run_command("VOLDDUMP",10,"vdc","dump",NULL);
run_command("SECURECONTAINERS",10,"vdc","asec","list",NULL);
run_command("PROCESSES",10,"ps","-P",NULL);
run_command("PROCESSESANDTHREADS",10,"ps","-t","-p","-P",NULL);
run_command("LIBRANK",10,"librank",NULL);
run_command("FILESYSTEMS&FREESPACE",10,"df",NULL);
run_command("LASTRADIOLOG",10,"parse_radio_log","/proc/last_radio_log",NULL);
run_command("DUMPSYS",60,"dumpsys",NULL);
4、Dumpsys
I:
\00_AndriodSource\android-gingerbread-src\frameworks\base\cmds\dumpsys
constsize_tN=services.size();
if(N>1){
//firstprintalistofthecurrentservices
aout<<"Currentlyrunningservices:
"<for(size_ti=0;ispservice=sm->checkService(services[i]);
if(service!
=NULL){
aout<<""<}
}
}
for(size_ti=0;ispservice=sm->checkService(services[i]);
if(service!
=NULL){
if(N>1){
aout<<"------------------------------------------------------------"
"-------------------"<aout<<"DUMPOFSERVICE"<"<}
interr=service->dump(STDOUT_FILENO,args);//调用每个service中的dump()方法输出log
if(err!
=0){
aerr<<"Errordumpingserviceinfo:
("<<<")"<}
}else{
aerr<<"Can'tfindservice:
"<}
}
输出log信息代码如上,结合实际log分析,dumpsys输出系统服务dump信息
七其他方法技巧
1、通过设置系统属性打开log开关
如有如下打印log的代码:
if(Log.isLoggable(TAG,Log.DEBUG)){
Log.d(TAG,"RedirectrequestedbutnoLocation"
+"specified.");
}
我们只需要通过设置系统属性就可以打印出这个log,而不用修改代码。
可以通过setprop命令或修改build.prop来达到目的。
具体见Log.java中的介绍:
/**
*Checkstoseewhetherornotalogforthespecifiedtagisloggableatthespecifiedlevel.
*
*ThedefaultlevelofanytagissettoINFO.Thismeansthatanylevelaboveandincluding
*INFOwillbelogged.Beforeyoumakeanycallstoaloggingmethodyoushouldchecktosee
*ifyourtagshouldbelogged.Youcanchangethedefaultlevelbysettingasystemproperty:
*'setproplog.tag.<YOUR_LOG_TAG><LEVEL>'
*WhereleveliseitherVERBOSE,DEBUG,INFO,WARN,ERROR,ASSERT,orSUPPRESS.SUPRESSwill
*turnoffallloggingforyourtag.Youcanalsocreatealocal.propfilethatwiththe
*followinginit:
*'log.tag.<YOUR_LOG_TAG>=<LEVEL>'
*andplacethatin/data/local.prop.
*
*@paramtagThetagtocheck.
*@paramlevelTheleveltocheck.
*@returnWhetherornotthatthisisallowedtobelogged.
*@throwsIllegalArgumentExceptionisthrownifthetag.length()>23.
*/
publicstaticnativebooleanisLoggable(Stringtag,intlevel);
1.查看当前堆栈
1)功能:
在程序中加入代码,使可以在logcat中看到打印出的当前函数调用关系
2)方法:
newException(“printtrace”).printStackTrace();
2.MethodTracing
1)功能:
用于热点分析和性能优化,分析每个函数占用的CPU时间,调用次数,函数调用关系等
2)方法:
a)在程序代码中加入追踪开关
importandroid.os.Debug;
……
android.os.Debug.startMethodTracing(“/data/tmp/test”);//先建/data/tmp目录
……//被追踪的程序段
android.os.Debug.stopMethodTracing();
b)编译,运行后,设备端生成/data/tmp/test.trace文件
c)把trace文件复制到PC端
$adbpull/data/tmp/test.trace./
d)使用android自带工具分析trace文件
$$ANDROID_SRC/out/host/linux-x86/bin/traceviewtest.trace
此时可看到各个函数被调用的次数CPU占用率等信息
e)使用android自带工具分析生成调用关系类图
$apt-getinstallgraphviz#安装图片相关软件
$ANDROID_SRC/out/host/linux-x86/bin/dmtracedump-gtest.pngtest.trace
此时目录下生成类图test.png
3)注意
trace文件生成与libdvm模块DEBUG版本相冲突,所以此方法只适用于对非DEBUG版本模拟器的调试,否则在分析trace文件时会报错
3.HProf(HeapProfile)
1)功能:
用于java层面的内存分析,显示详细的内存占用信息,指出可疑的内存泄漏对象