记录一次Skia JNI 库的崩溃

2021-07-06  本文已影响0人  小跑777

发现问题

在白板应用中发现出现偶发的崩溃, 堆栈上看,崩溃发生在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 的接口不是线程安全的

问题解决

上一篇下一篇

猜你喜欢

热点阅读