美文网首页
记录一次Skia JNI 库的崩溃

记录一次Skia JNI 库的崩溃

作者: 小跑777 | 来源:发表于2021-07-06 15:49 被阅读0次

    发现问题

    在白板应用中发现出现偶发的崩溃, 堆栈上看,崩溃发生在skia native层,但是问题原因未知

    2021-07-06 15:09:26.750 7505-7534/com.ruijie.whiteboard.debug A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 7534 (Thread-3)
    2021-07-06 15:09:26.772 7539-7539/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    2021-07-06 15:09:26.772 7539-7539/? A/DEBUG: Build fingerprint: 'google/sdk_google_atv_x86/generic_x86:8.0.0/OSR1.180418.025/6695156:userdebug/test-keys'
    2021-07-06 15:09:26.772 7539-7539/? A/DEBUG: Revision: '0'
    2021-07-06 15:09:26.772 7539-7539/? A/DEBUG: ABI: 'x86'
    2021-07-06 15:09:26.772 7539-7539/? A/DEBUG: pid: 7505, tid: 7534, name: Thread-3  >>> com.ruijie.whiteboard.debug <<<
    2021-07-06 15:09:26.773 7539-7539/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    2021-07-06 15:09:26.773 7539-7539/? A/DEBUG: Cause: null pointer dereference
    2021-07-06 15:09:26.773 7539-7539/? A/DEBUG:     eax 8a6d14fe  ebx 00000002  ecx 00000002  edx 00000000
    2021-07-06 15:09:26.773 7539-7539/? A/DEBUG:     esi 9837b580  edi a440b050
    2021-07-06 15:09:26.773 7539-7539/? A/DEBUG:     xcs 00000073  xds 0000007b  xes 0000007b  xfs 0000003b  xss 0000007b
    2021-07-06 15:09:26.773 7539-7539/? A/DEBUG:     eip a51eb4bc  ebp 88d78c68  esp 88d78c18  flags 00010202
    2021-07-06 15:09:27.052 7539-7539/? A/DEBUG: backtrace:
    2021-07-06 15:09:27.052 7539-7539/? A/DEBUG:     #00 pc 0001a4bc  /system/lib/libc.so (memcpy+716)
    2021-07-06 15:09:27.052 7539-7539/? A/DEBUG:     #01 pc 0031bb53  /system/lib/libskia.so (_ZN9SkPathRef21CreateTransformedCopyEP5sk_spIS_ERKS_RK8SkMatrix+339)
    2021-07-06 15:09:27.052 7539-7539/? A/DEBUG:     #02 pc 003148c8  /system/lib/libskia.so (_ZNK6SkPath9transformERK8SkMatrixPS_+104)
    2021-07-06 15:09:27.052 7539-7539/? A/DEBUG:     #03 pc 00112265  /system/lib/libandroid_runtime.so (_ZN7android10SkPathGlue17transform__MatrixEP7_JNIEnvP7_jclassxx+37)
    2021-07-06 15:09:27.052 7539-7539/? A/DEBUG:     #04 pc 00a37ab2  /system/framework/x86/boot-framework.oat (offset 0x5e9000) (android.content.res.AssetManager.copyTheme [DEDUPED]+178)
    2021-07-06 15:09:27.052 7539-7539/? A/DEBUG:     #05 pc 00004b25  /dev/ashmem/dalvik-jit-code-cache (deleted)
    

    问题代码抽取

    从业务逻辑中抽取了一段最简单的逻辑,且能够稳定复现崩溃

    
        @Test
        fun start() {
            val path = Path()
            path.moveTo(373.532f, 212.3455f)
            path.quadTo(324.238f, 280.8409f, 898.283f, 142.2339f)
            var pathMeasure = PathMeasure(path, false)
            Thread {
                while (true) {
                    Log.i("llbeing", "${Thread.currentThread().id} 1")
                    path.transform(randomMatrix())
                    Log.i("llbeing", "${Thread.currentThread().id} 2")
                    pathMeasure.setPath(path, false)
                    Log.i("llbeing", "${Thread.currentThread().id} 3")
                }
            }.start()
    
            Thread {
                while (true) {
                    Log.i("llbeing", "${Thread.currentThread().id} 1")
                    path.transform(randomMatrix())
                    Log.i("llbeing", "${Thread.currentThread().id} 2")
                    pathMeasure.setPath(path, false)
                    Log.i("llbeing", "${Thread.currentThread().id} 3")
                }
            }.start()
        }
    
        private fun randomMatrix(): Matrix {
            val matrix = Matrix()
            matrix.setTranslate(random.nextFloat(), random.nextFloat())
            return matrix
        }
    

    问题分析

    从日志中可以依稀看出来,问题调用栈是:

    1. path.transform(matrix)
    2. Path.cpp
    3. SkPathGlue::transform
    4. SkPath.transform
    5. SkPathRef::CreateTransformedCopy
    6. sk_careful_memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(),src.fVerbCnt * sizeof(uint8_t));
    

    然后崩溃

    native 层逻辑无从考究,猜测可能是,多线程读写的问题,memcpy 时由于src的fVerbCnt 被其他线程修改导致当前线程的崩溃
    可见Skia 的接口不是线程安全的

    问题解决

    • 访问对象加锁
    • 不使用同一个对象

    相关文章

      网友评论

          本文标题:记录一次Skia JNI 库的崩溃

          本文链接:https://www.haomeiwen.com/subject/uhugultx.html