修复chromium浏览器内核crash,[FATAL:jni_android.cc(289] Please include Java exception stack in crash report

一、问题

Google Play 出现crash 日志上报, 而 firebase异常监控系统没有补货到, 此为 Chromium 内核的异常。Android WebView 出现Crash

Google Play 日志

[FATAL:jni_android.cc(289)] Please include Java exception stack in crash report
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 14120 >>> com.app <<<

backtrace:
  #00  pc 0x00000000030989a4  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #01  pc 0x000000000285d830  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #02  pc 0x000000000285c870  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #03  pc 0x000000000742e8b0  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #04  pc 0x000000000742ed10  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #05  pc 0x00000000020734cc  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #06  pc 0x0000000003176904  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #07  pc 0x0000000003176804  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #08  pc 0x0000000002836fb4  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #09  pc 0x0000000002836b8c  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #10  pc 0x00000000028363f8  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #11  pc 0x000000000283489c  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #12  pc 0x000000000283d6c0  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #13  pc 0x000000000283d62c  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #14  pc 0x0000000002873c20  /data/app/~~kJGMXqH6dsC0IYqR21nD_w==/com.google.android.trichromelibrary_573513033-fZajnopyPyFsb3G5FKgEyA==/base.apk!libmonochrome_64.so
  #15  pc 0x00000000000b6974  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264)
  #16  pc 0x0000000000053210  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68)

二、分析

是什么原因导致WebView Chrom内核出现的异常错误呢?
从日志中无法直接定位是何原因导致,通过配置开关可知道是资源拦截时导致crash 数量的上涨。

思路:
一方面,分析线上监控系统1.firebase和kibana 的crash的错误上报,解决webview被捕获的crash 问题,进行解决。问题统计列表:

另一方面通过不断检查代码进行分析, 目前猜想有二。
一: Fresco框架sdk缓存及读取图片时出现的问题,或sdk转化为可关闭的流给浏览器读取时出现了问题;
二: 所有的拦截资源将本地文件转换为流的方式可能会出现异常,例如,浏览器访问的时候,这个流关闭了导致chrome异常;

进一步确认以上两个猜想,需进一步验证。
将图片拦截关闭(待firebase下发100%时),开启css/js拦截,是否会出现同样的crash 上涨。
若出现同样的上涨,那需要从猜想二入手, 如没有上涨,则从猜想一入手。

经过数据监控后,定位到还是Image资源拦截的问题

为什么还是呢?

因为之前在开发过程中就出现过

具体看https://editor.csdn.net/md/?articleId=130156454

Image资源方案是桥接使用Fresco下载图片字节流供webview 使用的

还得从fresco下手

经过某些努力,日志平台里复现关键日志

2023-07-04 21:52:42.269 22744-23120 System.err                          W  	at org.chromium.components.embedder_support.util.InputStreamUtil.available(chromium-TrichromeWebViewGoogle6432.aab-stable-573513133:1)
2023-07-04 21:52:42.270 22744-23120 chromium                            A  [FATAL:jni_android.cc(289)] Please include Java exception stack in crash report
2023-07-04 21:52:42.289 22744-23147 System.err                          W  	at org.chromium.components.embedder_support.util.InputStreamUtil.available(chromium-TrichromeWebViewGoogle6432.aab-stable-573513133:1)
2023-07-04 21:52:42.289 22744-23147 chromium                            A  [FATAL:jni_android.cc(289)] Please include Java exception stack in crash report
2023-07-04 21:52:42.290 22744-23137 System.err                          W  	at org.chromium.components.embedder_support.util.InputStreamUtil.available(chromium-TrichromeWebViewGoogle6432.aab-stable-573513133:1)
2023-07-04 21:52:42.290 22744-23137 chromium                            A  [FATAL:jni_android.cc(289)] Please include Java exception stack in crash report
2023-07-04 21:52:42.309 22744-23148 System.err                          W  	at org.chromium.components.embedder_support.util.InputStreamUtil.available(chromium-TrichromeWebViewGoogle6432.aab-stable-573513133:1)
2023-07-04 21:52:42.309 22744-23148 chromium                            A  [FATAL:jni_android.cc(289)] Please include Java exception stack in crash report
2023-07-04 21:52:42.414 22744-23117 System.err                          W  	at org.chromium.components.embedder_support.util.InputStreamUtil.available(chromium-TrichromeWebViewGoogle6432.aab-stable-573513133:1)
2023-07-04 21:52:42.414 22744-23117 chromium                            A  [FATAL:jni_android.cc(289)] Please include Java exception stack in crash report
2023-07-04 21:52:42.427 29614-29614 chromium                pid-29614                            E  [0704/215242.427039:ERROR:elf_dynamic_array_reader.h(64)] tag not found
--------- beginning of crash
2023-07-04 21:52:42.488 29614-29614 chromium                pid-29614                            E  [0704/215242.487997:ERROR:file_io_posix.cc(144)] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq: Permission denied (13)
2023-07-04 21:52:42.652 22744-23118 System.err                         W  	at org.chromium.components.embedder_support.util.InputStreamUtil.available(chromium-TrichromeWebViewGoogle6432.aab-stable-573513133:1)
2023-07-04 21:52:42.652 22744-23118 chromium                           A  [FATAL:jni_android.cc(289)] Please include Java exception stack in crash report
2023-07-04 21:52:42.716  1437-4678  ActivityManager         system_server                        I  Process com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 23115) has died: fg  BTOP(1020,2508)
2023-07-04 21:52:42.718  1437-4678  ActivityManager         system_server                        W  Scheduling restart of crashed service com.app/org.chromium.content.app.SandboxedProcessService0:0 in 1000ms for connection
---------------------------- PROCESS ENDED (22744) for package com.app ----------------------------

available??? 出现能读取到流 小于实际流的大小? 不完整的流给浏览器使用确实会出现chromium异常

三、方案

方案1: 重写PooledByteBufferInputStream 的 available
结论: 不crash,但是部分图片展示失败,流不完整

方案2: 释放流 IOHelper.closeQuietly(inputStream);
结论: 不crash,但是部分图片展示失败

方案3: 使用 ByteArrayInputStream
结论: 不crash,但是部分图片展示失败

方案4: 使用bitmap 转inputStream
结论:慢,图片类型限制

方案5:设置ImageRequest下载配置
结论:无效

方案6: 使用fetchDecodedImage CloseableImage
结论:可行,占用内存大,目前最优
缺点:下载保存的是解码后的图片,比起保存未解码的数据,由浏览器读取时自己解码,这大大增加缓存压力。

。。。

终于。 出现关键日志

W  com.facebook.common.memory.PooledByteBuffer$ClosedException: Invalid bytebuf. Already closed
2023-07-06 18:23:05.145 17534-17862 System.err             W  	at com.facebook.imagepipeline.memory.MemoryPooledByteBuffer.ensureValid(MemoryPooledByteBuffer.java:102)
2023-07-06 18:23:05.145 17534-17862 System.err             W  	at com.facebook.imagepipeline.memory.MemoryPooledByteBuffer.size(MemoryPooledByteBuffer.java:44)
2023-07-06 18:23:05.145 17534-17862 System.err             W  	at com.swing.helper.PooledByteBufferInputStream.available(PooledByteBufferInputStream.java:45)
2023-07-06 18:23:05.145 17534-17860 System.err             W  com.facebook.common.memory.PooledByteBuffer$ClosedException: Invalid bytebuf. Already closed
2023-07-06 18:23:05.145 17534-17860 System.err             W  	at com.facebook.imagepipeline.memory.MemoryPooledByteBuffer.ensureValid(MemoryPooledByteBuffer.java:102)
2023-07-06 18:23:05.145 17534-17860 System.err             W  	at com.facebook.imagepipeline.memory.MemoryPooledByteBuffer.size(MemoryPooledByteBuffer.java:44)
W  com.facebook.common.memory.PooledByteBuffer$ClosedException: Invalid bytebuf. Already closed

好熟悉

又是https://editor.csdn.net/md/?articleId=130156454

看来,在预取的图片数量和图片流很大时,clone后,fresco 关闭了这个流还是会导致浏览器读取流时该流已经被关闭了

之所以什么的日志是定位到available(), 那是因为读流时首先就是通过available()获取可读流的大小,若此时流已关闭将出现异常

四、原因

在image拦截中,使用Fresco缓存方式,使用了可关闭的引用(CloseableReference)
根据Fresco API 在赋值给变量前,先进行clone。

然而,clone后, 某些场景还是会出现 ClosedException: Invalid bytebuf. Already closed

五、解决

最终方案
不使用用官方的clone, 自己重写流

byte[] bytesBuffer = new byte[buffer.size()];
buffer.read(0, bytesBuffer, 0, buffer.size());
inputStream = new ByteArrayInputStream(bytesBuffer);

六、总结

  1. bug总会有,有bug解bug嘛
  2. 需先定位是什么原因导致的
  3. 分析,多维度,定位
  4. 官方API又如何
  5. 关键复现

七、引用

https://editor.csdn.net/md/?articleId=130156454

八、最后

此文章为个人开发时记录,有时时间有限,无法深入研究,若看到此文章后有其他见解或解决方式,欢迎留言交流👇👇👇
————————————————
版权声明:转载请附上原文出处链接及本声明。
原文链接:
https://editor.csdn.net/md/?articleId=131616156

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐