Hi, I’m developer from UC Browser team, Alibaba Groups.
Our app is suffering from some crash in hwui for a long time, which is the highest crash reason in UC Browser App in China.
Crash Stack:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000010
r0 00000000 r1 00000000 r2 d3575428 r3 00000cf3
r4 d3575428 r5 d597f408 r6 00000000 r7 d597f374
r8 d597f380 r9 f3c33268 10 f3c332e0 fp f39eea40
ip d3dd7008 sp d597f340 lr f3bd8487 pc f3c14a8e cpsr 600f0030
>>> [translate by crash parser] <<<
00 pc 0005ea8e /system/lib/libhwui.so
01 pc 00022483 /system/lib/libhwui.so
02 pc 000220e9 /system/lib/libhwui.so
03 pc 00023cb7 /system/lib/libhwui.so
04 pc 0002713d android::uirenderer::renderthread::RenderThread::threadLoop() LINE:libhwui.so
05 pc 0000e395 android::Thread::_threadLoop(void*) LINE:libutils.so
06 pc 00058621 android::AndroidRuntime::javaThreadShell(void*) LINE:libandroid_runtime.so
07 pc 00047463 __pthread_start(void*) LINE:libc.so
08 pc 00019e2d __start_thread LINE:libc.so
As I dissassembled the code data given by PC register, I got some instruments like:
f54cba28: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
f54cba2c: af03 add r7, sp, #12
f54cba2e: b08a sub sp, #40 ; 0x28
f54cba30: 466c mov r4, sp
f54cba32: f36f 0403 bfc r4, #0, #4
f54cba36: 46a5 mov sp, r4
f54cba38: 4605 mov r5, r0
f54cba3a: 484e ldr r0, [pc, #312] ; (0xf54cbb74)
f54cba3c: 4614 mov r4, r2
f54cba3e: 460e mov r6, r1
f54cba40: 4478 add r0, pc
f54cba42: 6800 ldr r0, [r0, #0]
f54cba44: 6800 ldr r0, [r0, #0]
f54cba46: 9009 str r0, [sp, #36] ; 0x24
f54cba48: 6968 ldr r0, [r5, #20]
f54cba4a: 2800 cmp r0, #0
f54cba4c: d170 bne.n 0xf54cbb30
f54cba4e: ed96 0a04 vldr s0, [r6, #16] --> PC pointed to here, in different version libhwui.so, we can find the same instrument sequence just once.
f54cba52: eeb8 2a40 vcvt.f32.u32 s4, s0
f54cba56: ec94 0a02 vldmia r4, {s0-s1}
f54cba5a: eeb5 0ac0 vcmpe.f32 s0, #0.0
I succeeded to find the corresponeding code in Android Source:
void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) {
LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
// subtract repaintRect from region, since it will be regenerated
if (repaintRect.contains(0, 0,
offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight)) { ----------> HERE, because of offscreenBuffer was NULL.
// repaint full layer, so throw away entire region
offscreenBuffer->region.clear();
} else {
offscreenBuffer->region.subtractSelf(android::Rect(repaintRect.left, repaintRect.top,
repaintRect.right, repaintRect.bottom));
}
And I guessed the callback stack:
Crash Stack:
>>> [translate by crash parser] <<<
00 pc 0005ea8e /system/lib/libhwui.so --> BakedOpRenderer::startRepaintLayer(From PC)
01 pc 00022483 /system/lib/libhwui.so --> frameBuilder::replayBakedOps<BakedOpDispatcher> (From LR)
02 pc 000220e9 /system/lib/libhwui.so Guessed --> RenderContext::buildLayer
03 pc 00023cb7 /system/lib/libhwui.so Guessed --> MethodInvokeRenderTask::run()
04 pc 0002713d android::uirenderer::renderthread::RenderThread::threadLoop() LINE:libhwui.so
05 pc 0000e395 android::Thread::_threadLoop(void*) LINE:libutils.so
06 pc 00058621 android::AndroidRuntime::javaThreadShell(void*) LINE:libandroid_runtime.so
07 pc 00047463 __pthread_start(void*) LINE:libc.so
08 pc 00019e2d __start_thread LINE:libc.so
The data flow of offscreenBuffer is like:
offscreenBuffer <--- LayerBuilder::offscreenBufer <--- RenderNode::mLayer
I do notice RenderNode::mLayer will set to null_ptr for some reason, and I don't know how the libhwui.so to guarantee RenderNode::mLayer is not null when calling startRepaintLayer.
Here go my question:
1. Did anyone notice the same kind of crash in BakedOpRenderer::startRepaintLayer?
2. How the libhwui.so to guarantee RenderNode::mLayer is not null when calling startRepaintLayer?