记录一次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 的接口不是线程安全的
问题解决
- 访问对象加锁
- 不使用同一个对象