做 Android 开发,打 log 是常规操作。
某天收到反馈说 log 丢失 (黑人问号脸),这里记录下探索过程。
系统默认的 log 缓冲区比较小,logcat 可能出现 read: unexpected EOF!
的情况,这样 log 就中断了,不再输出。
查看缓冲区大小
logcat -g
真机上验证
xxx:/ # logcat -g
main: ring buffer is 256Kb (233Kb consumed), max entry is 5120b, max payload is 4068b
system: ring buffer is 256Kb (231Kb consumed), max entry is 5120b, max payload is 4068b
crash: ring buffer is 256Kb (0b consumed), max entry is 5120b, max payload is 4068b
修改缓冲区大小,可以再大一点,别太离谱就行。
logcat -G 10m
重启后设置的缓冲区大小会被还原,需要重新设置。
问题来了,改系统源码怎么改?
AN 8.0 ,修改 system/core/liblog/include/private/android_logger.h
文件,
#define LOG_BUFFER_SIZE (256 * 1024) /* Tuned with ro.logd.size per-platform \
*/
#define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
修改 LOG_BUFFER_MAX_SIZE 为自己定义的大小。
修改后烧录软件使用 logcat -g
命令查看是否有效。待验证。
AN 8.0 ,源码 system/core/liblog/include/log/log_read.h
里定义了 log 显示的长度,超过这个长度就无法正常显示 log 了。
/*
* The maximum size of a log entry which can be read.
* An attempt to read less than this amount may result
* in read() returning EINVAL.
*/
#define LOGGER_ENTRY_MAX_LEN (5 * 1024)
如何验证?简单,写个暴力 demo
private void test(){
StringBuilder sBuilder = new StringBuilder();
for (int i = 0 ; i < 5000; i++){
sBuilder.append("s");
if(i > 4900){
Log.d("test", "[MainActivity.java] -- test -- i:" + i);
Log.d("test", "[MainActivity.java] -- test -- sBuilder:" + sBuilder.toString());
}
}
}
测试 i = 4626 的时候, log 就被截断不显示了。