赞
踩
之前我们分析过关于Android log机制,在这里我们再详细说下,log丢失的原理。
logd监听了logdw的socket来保存从log打印函数通过logdw socket传过来的log,最后会调用LogBuffer::log函数,在log函数最后会调用如下两个函数。
这里的log_id就是radio,main,event等。
我们先来看LogStatistics::add函数
这个函数,对每个log_id的消息长度做统计,消息数量也做了统计。
我们再来看下这个maybePrune函数
在之前的博客中我们分析过了,每个log_id的size是如何而来的。可以通过属性获取。
这里保存elements的是mLogElements,只是保存的LogBufferElement 的指针而已,实际不会占用多大的内存。
而且只有每个element被调用erase,才会被真正销毁内存。
所以每个log_id设定的值,不是一个缓存,而是一个警戒值。超过这个值,就要对特定log删除。
prune函数主要就是删除log,在删除log的时候也做了白名单和黑名单的机制。
这里我们先来看看LogBuffer的initPrune函数,这是用来设定白名单和黑名单的。
至于init这个函数我们就不看了,主要是解析字符串,把uid,pid保存下来。
那么又在哪里设定白名单和黑名单呢?我们可以通过如下命令,最后就调用了initPrune函数来设定白黑名单了。
而每个白名单和黑名单的匹配就是看uid和pid的。这块就不细看了。
下面我们就来看下prune这个函数的黑名单部分处理:
上面就是对黑名单以及log最多的那个uid的处理,我们先来看看每个LogBufferElement的setDropped函数
这个函数直接把消息清空了,然后把mDropped设为1,我们再来看看last.merge(e, 1)函数
下面我们再看下白名单处理:
白名单的处理比较简单,只要是白名单的不删除,其他都删除,直到满足条件。
之前的博客分析过当logcat进程到logd中取log时,会最终调用LogBufferElement::flushTo函数
调用populateDroppedMessage函数最终会把消息设为类似:
最后总结,在logd中如果有丢失log,可以设置log_id的缓冲设置再大写。如果是调试的话可以增加调试的白名单。而且在logd中丢失log肯定会有类似chatty这样的log,那就是删除了log最多的那个uid的log。而且会合并。
我们可以通过设置系统属性persist.logd.size来设置每个log id的最大缓存值(在开发者选项中也有这个设置,开发者选项中设置就不用重启设备了),或者persist.logd.size.radio设置每个id的最大缓存值。
步骤:
将手机连上电脑并且进入root
setproppersist.logd.size.radio 1024k
reboot 重启
另外可以用getprop | grep logd查看设置的属性是否生效
logcat -g 可以查看每个id 的缓存大小
当然这是通过属性的方法设置,我们还可以通过logcat的命令,logcat -G 10m是设置所有的id的大小,logcat -b radio -G 10m是设置radio的log的缓存大小
在logcat中有如下代码,处理设置缓存大小
如果logd中没有chatty这样的log,但是又有log丢失,那么就要怀疑在写log时,logdw的socket就有丢失。因为我们看下logdw是dgram类型的,这种socket是一种不可靠的报文传递保证效率但会有丢失。所有这样情况我们可以看把socket改成stream试试,看看是否有效果?
但是试了以后好像socket在连接的时候就有问题。
后续我们使用android4.4的的机制 kernel的log机制,这样就不会有丢失问题。
原文地址: http://blog.csdn.net/kc58236582/article/details/51506896
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。