首页 > 解决方案 > 三星设备上的本机崩溃高峰

问题描述

上个月,我在 Google Play Console 上看到了原生崩溃的高峰,它们来自三星设备,其中 98% 主要是 Android 10 (90%),其次是 Android 9 (10%)。超过一半的案例是关于三星 S9 设备的,而其余的则是关于最近的设备型号(三星 s10+、Note9 等)。

有堆栈跟踪:

  #00  pc 0000000000083360  /apex/com.android.runtime/lib64/bionic/libc.so (abort+176)
  #01  pc 0000000000008a74  /system/lib64/liblog.so (__android_log_assert+324)
  #02  pc 00000000003fb0dc  /system/lib64/libhwui.so (android::uirenderer::renderthread::EglManager::swapBuffers(android::uirenderer::renderthread::Frame const&, SkRect const&)+276)
  #03  pc 00000000003fae4c  /system/lib64/libhwui.so (android::uirenderer::skiapipeline::SkiaOpenGLPipeline::swapBuffers(android::uirenderer::renderthread::Frame const&, bool, SkRect const&, android::uirenderer::FrameInfo*, bool*)+92)
  #04  pc 0000000000407c8c  /system/lib64/libhwui.so (android::uirenderer::renderthread::CanvasContext::draw()+716)
  #05  pc 0000000000406d38  /system/lib64/libhwui.so (_ZNSt3__110__function6__funcIZN7android10uirenderer12renderthread13DrawFrameTask11postAndWaitEvE3$_0NS_9allocatorIS6_EEFvvEEclEv$c303f2d2360db58ed70a2d0ac7ed911b+216)
  #06  pc 0000000000417a44  /system/lib64/libhwui.so (android::uirenderer::WorkQueue::process()+228)
  #07  pc 0000000000417770  /system/lib64/libhwui.so (android::uirenderer::renderthread::RenderThread::threadLoop()+80)
  #08  pc 00000000000137a4  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+284)
  #09  pc 00000000000e3b14  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
  #10  pc 0000000000085330  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

此外,仅三星设备和仅 Android 10 也出现了另一个问题(设备型号分布似乎很随机):没有采取任何特别行动就解决了这个问题

#00  pc 0000000002cfeadc  /data/app/com.google.android.webview-8w0eiuwFhdVaEviNzD1U7g==/base.apk!libmonochrome.so (offset 0x15b000)

我不知道是什么导致了这个问题,但我也附上了我的build.gradle文件依赖项,因为这些问题通常与谷歌库有关。

有没有人看到同样的问题?

更新 关于第一个问题,我对发生崩溃的应用程序活动应用的主要更改之一是关于更新的 Android 视图绑定。由于崩溃似乎与UI有关,因此可能是这种情况。有人也使用视图绑定吗?

更新 2 看起来切换到旧的findViewById(仅在崩溃时处于活动状态的 Activity 中)而不是使用 View Binding 使问题消失了。目前我正在一小群 beta 测试人员中对其进行测试,但此时我应该已经看到了一些崩溃报告。我会不断更新这篇文章。

更新 3 ─ 2022 随着 Android 11 的最新更新,一些事情发生了变化,尤其是这个。我不知道是因为我切换到 API 31 还是因为我再次上传了 Crashlytics 符号,但现在我在 Google Play 控制台中看到了很多新的崩溃报告:

  #00  pc 0000000000053350  /apex/com.android.runtime/lib64/bionic/libc.so (fdsan_error(char const*, ...)+588)
  #00  pc 000000000005304c  /apex/com.android.runtime/lib64/bionic/libc.so (android_fdsan_close_with_tag+736)
  #00  pc 0000000000053884  /apex/com.android.runtime/lib64/bionic/libc.so (close+16)
  #00  pc 000000000000371c  /system/lib64/libTcpOptimizer.mobiledata.samsung.so (close+220)
  #00  pc 00000000001e7c24  /vendor/lib64/libgsl.so (!!!0000!6a7f7ec785028d96437db04399d932!4e552d6!+28)
  #00  pc 00000000000bb5f8  /vendor/lib64/libgsl.so (gsl_syncobj_destroy+152)
  #00  pc 000000000025d538  /vendor/lib64/egl/libGLESv2_adreno.so (!!!0000!10f39af3d5dda97a64124dee6a3783!4e552d6!+456)
  #00  pc 0000000000244ff8  /vendor/lib64/egl/libGLESv2_adreno.so (!!!0000!04fe7c7713a0660472688458ecb7a2!4e552d6!+144)
  #00  pc 000000000002b928  /system/lib64/libEGL.so (android::eglSwapBuffersWithDamageKHRImpl(void*, void*, int*, int)+776)
  #00  pc 0000000000027ea4  /system/lib64/libEGL.so (eglSwapBuffersWithDamageKHR+72)
  #00  pc 00000000003b0724  /system/lib64/libhwui.so (android::uirenderer::renderthread::EglManager::swapBuffers(android::uirenderer::renderthread::Frame const&, SkRect const&)+176)
  #00  pc 00000000003a3e30  /system/lib64/libhwui.so (android::uirenderer::skiapipeline::SkiaOpenGLPipeline::swapBuffers(android::uirenderer::renderthread::Frame const&, bool, SkRect const&, android::uirenderer::FrameInfo*, bool*)+92)
  #00  pc 00000000003ac81c  /system/lib64/libhwui.so (android::uirenderer::renderthread::CanvasContext::draw()+1196)
  #00  pc 00000000003ae9e4  /system/lib64/libhwui.so (_ZNSt3__110__function6__funcIZN7android10uirenderer12renderthread13DrawFrameTask11postAndWaitEvE3$_0NS_9allocatorIS6_EEFvvEEclEv$c303f2d2360db58ed70a2d0ac7ed911b+524)
  #00  pc 000000000039cefc  /system/lib64/libhwui.so (android::uirenderer::WorkQueue::process()+208)
  #00  pc 00000000003bf0ec  /system/lib64/libhwui.so (android::uirenderer::renderthread::RenderThread::threadLoop()+88)
  #00  pc 000000000001553c  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+320)
  #00  pc 0000000000014db0  /system/lib64/libutils.so (thread_data_t::trampoline(thread_data_t const*)+408)
  #00  pc 00000000000b6234  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64)
  #00  pc 0000000000050e64  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

这似乎当然与上面链接的 fdsan 问题和两年前我看到的模糊中止堆栈跟踪有关。所以我开始深入研究我的代码,寻找任何与 fd 相关的错误,结果如下:

BUG #1:在代码中发现了一个错误,我在将文件描述符传递给 后从未关闭它[MediaExtractor].setDataSource(FileDescriptor),因为我认为[MediaExtractor].release(). 我错了

BUG #2:在 JNI 代码中发现了另一个微妙的错误,我正在接收一个文件描述符,我用它来打开一个流,fdopen()然后fclose()在完成时关闭它。整个流是在第三方库中制作的,我不知道——或者我并不真正关心——而且我调用close()了同一个已经关闭的文件描述符。这导致了所谓的双重关闭错误,你猜怎么着?fdsan 负责检测这种错误然后中止。在 Android 11 之前,fdsan 的行为只是输出无声警告,但随后默认设置更改为致命中止信号。这不可能是巧合……?

我向 beta 测试人员发送了包含上述修复的应用程序版本。期待发布一些积极的结果。

标签: android

解决方案


即使我在应用程序中的一些广告中也经历过这种崩溃。即使您可以通过调用 webview.loadUrl("chrome://crash") 来重现 webview 崩溃,这应该会使您的 webview 崩溃并且您将能够重现该场景。

抑制这些崩溃的唯一方法是在 webview 客户端中覆盖onRenderProcessGone并自行处理崩溃,在这种情况下,Ads SDK 必须处理,因为 webview 是由它们实现的。

参考:https ://github.com/mopub/mopub-android-sdk/issues/312


推荐阅读