解决Android logcat: Unexpected EOF!方法指南



引言

  又有好久没有写点偏重实战类型的博客了,最近一直都在捣鼓源码分析和项目相关事情,是时候来点偏重实战类型的博客了。捯饬点啥实战的呢,正好这两天有忙着新项目的开发工作,在发现使用logcat进行相关调试的时候一直会提示logcat给奔溃了!纳尼,这是什么屁错误,还是第一次遇到。

logcat: Unexpected EOF!

This means that either the device shut down, logd crashed, or this instance of logcat was unable to read log
messages as quickly as they were being produced.

If you have enabled significant logging, look into using the -G option to increase log buffer sizes.

遇到了问题,我们必须解决问题不是!解决实质性的问题,没有啥好技巧可言的,这里我直接来说我的解决思路和方法。

如果读者朋友比较着急,没有耐心听我慢慢细说前因后果,可以直接跳入第二章节查找解决方法!

并且这里补充一点,在调试的时候如果logcat刷屏太快,信息处理不过来可以通过logcat -f logcat.txt将缓冲信息保存到日志文件中,这样就比较便于查看了!




一.定位问题

没有啥好说的,直接分析问题解决问题,快准狠!

通过错误日志来看,问题很明显是logcat的日志缓冲区给刷爆了导致的,

This means that either the device shut down, logd crashed, or this instance of logcat was unable to read log
messages as quickly as they were being produced.

对于此问题有点类似消费者/生产者模型,输出的日志有点像生产者由于没有节制没有规划量大于求,生产过多了导致仓库爆单,工厂生产无法正常进行了,而这里的日志缓冲区就是消费者了由于消费者数量有限无法完全消费完生产者生产的产品从而导致整套模型玩转不了了。此时就需要扩大内需,将消费者扩大了。

那么有什么方法可以查看logcat缓冲区大小的吗,当然有了,logcat提供了logcat -g的命令进行查看。我们来验证一番:

1|console:/ # logcat  -g
console:/ # logcat  -g                                                         
main: ring buffer is 64 KiB (1002 KiB consumed), max entry is 5120 B, max payload is 4068 B
system: ring buffer is 64 KiB (1010 KiB consumed), max entry is 5120 B, max payload is 4068 B
crash: ring buffer is 64 KiB (1001 KiB consumed), max entry is 5120 B, max payload is 4068 B
kernel: ring buffer is 64 KiB (0 B consumed), max entry is 5120 B, max payload is 4068 B

尼玛,这默认的日志缓冲区大小也太小了吗!竟然只有64K而已,而已啊。所以当我们在调试阶段,产生的日志过多的时候,就很容出现日志缓冲区被刷爆的问题了。




二.解决问题

既然定位了问题,那就得解决问题!这里我提供如下几种解决办法,供各位选择!


2.1 临时解决办法

这个解决办法比较临时,不能一劳永逸!发生错误的时候,错误信息已经为我们提供了logcat缓冲被刷爆的解决办法,如下::

If you have enabled significant logging, look into using the -G option to increase log buffer sizes.

看不懂,好吗,我来翻译一下!上述的意思是我们可以通过logcat -G来临时设置缓冲区的大小,我么尝试一下:

console:/ # logcat  -G 5M
console:/ # logcat  -g                                                         
main: ring buffer is 5 MiB (1002 KiB consumed), max entry is 5120 B, max payload is 4068 B
system: ring buffer is 5 MiB (1010 KiB consumed), max entry is 5120 B, max payload is 4068 B
crash: ring buffer is 5 MiB (1001 KiB consumed), max entry is 5120 B, max payload is 4068 B
kernel: ring buffer is 5 MiB (0 B consumed), max entry is 5120 B, max payload is 4068 B

这里我们可以看到,设置缓冲区成功。此时需要通过logcat进行调试的时候,就不会出现缓冲区拉爆的情况了。


2.2 通过界面设置

从Android 5.0开始,在开发者选项中,可以通过显示/允许增加环形缓冲区的大小,进行相关的缓冲区的大小设置,如下所示:

在这里插入图片描述
在这里插入图片描述

我们来看下有没有设置成功,见证奇迹的时候到了

console:/ # logcat  -G 5M
console:/ # logcat  -g                                                         
main: ring buffer is 16 MiB (1002 KiB consumed), max entry is 5120 B, max payload is 4068 B
system: ring buffer is 16 MiB (1010 KiB consumed), max entry is 5120 B, max payload is 4068 B
crash: ring buffer is 16 MiB (1001 KiB consumed), max entry is 5120 B, max payload is 4068 B
kernel: ring buffer is 16 MiB (0 B consumed), max entry is 5120 B, max payload is 4068 B

2.3 永久解决

上述第一种方法,在关机之后会失效,那么有没有永久有效的办法解决呢,当然有了,我们可以在shell状态下的setporp命令修改属性值,通过此方法可以使其在重启后仍然有效,具体修改的属性为persist.logd.size的值的大小,我么来尝试一下:

setprop persist.logd.size 8M

此时需要重新启动才能使设置生效!重启之后,我们一起来见证奇迹:

console:/ $ logcat  -g                                                         
main: ring buffer is 8 MiB (43 KiB consumed), max entry is 5120 B, max payload is 4068 B
system: ring buffer is 8 MiB (7 KiB consumed), max entry is 5120 B, max payload is 4068 B
crash: ring buffer is 8 MiB (0 B consumed), max entry is 5120 B, max payload is 4068 B
kernel: ring buffer is 8 MiB (0 B consumed), max entry is 5120 B, max payload is 4068 B

此时可以看到我们已经修改成功了。

至于永久有效,我们可以把上述命令固化在Android源码中,譬如init.rc等中就可以达到永久有效了。

这里还提供一种方法,我们也可以通过修改驱动层logcat的实现来达到修改缓冲区大小的功能!它的修改在/kernel/drivers/staging/android/logger.c中,如下:

static int __init logger_init(void)
{
    int ret;

    ret = create_log(LOGGER_LOG_MAIN, 128*1024);
    if (unlikely(ret))
        goto out;

    ret = create_log(LOGGER_LOG_EVENTS, 128*1024);
    if (unlikely(ret))
        goto out;

    ret = create_log(LOGGER_LOG_RADIO, 128*1024);
    if (unlikely(ret))
        goto out;

    ret = create_log(LOGGER_LOG_SYSTEM, 128*1024);
    if (unlikely(ret))
        goto out;

out:
    return ret;
}

这里我们可以修改create_log的第二个参数的大小,同样可以达到目的。刚兴趣的读者可以自行尝试一下。

上述的源码中,我在Android 11中并没有找到,可能Android 11的实现有所改变了,读者如果有了解的可以告知一下。




写在最后

好了今天的博客解决Android logcat: Unexpected EOF!方法指南就到这里了,由于这是一篇实战类型的博客所以也没有多少总结的了,跟着干就行了。总之,青山不改绿水长流先到这里了。如果本博客对你有所帮助,麻烦关注或者点个赞,如果觉得很烂也可以踩一脚!谢谢各位了!!

这里给读者提出一个问题,上述的几种方法它们的优先级是什么呢。Android是怎么取舍的呢?读者朋友可以考虑一下。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐