Repository navigation
Description
[UPDATED 2026-07-16] Recurring SIGSEGV in libGLESv2_mtk.so on MediaTek Android 13 — root cause is driver job-pool exhaustion, NOT the #187404 idle-context race (workaround extension tested and ineffective)
Summary
Our production Flutter app crashes repeatedly with a null-pointer SIGSEGV inside the MediaTek vendor GL driver (/vendor/lib64/egl/libGLESv2_mtk.so), entered via glClear from the Impeller GLES backend on the raster thread.
The crash signature is identical to #187336 (fixed by the workaround in #187404), and this issue originally requested extending that workaround's API <= 29 gate to cover this Android 13 (API 33) device. We have since tested exactly that (PR #189534, locally built engine, verified via libflutter.so BuildId in the crash dump) — it does not fix the crash. With the workaround verifiably active, the device crashes the same way. Same-day instrumented reproductions show the actual failure mode:
The driver's internal job pool is exhausted, its job allocation returns null, and the driver's glClear path dereferences that null. Every crash is preceded within ~0.5s by this driver error burst on the crashing thread:
E IMGSRV : :1136: RM_GrowJobPool: Number of job pool chunks in use is too large to allow growth
E IMGSRV : :1197: Failed to grow job pool
E IMGSRV : :2800: RM_InsertJob_NoLock: Failed to allocate Job
F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid ... (1.raster)
So while the symptom matches the #187404 family, the mechanism does not: this is job-pool exhaustion under many small GL submissions, not the idle-context eglMakeCurrent race. Widening the #187404 gate (or platform list) will not help this device class.
Evidence (all same device, same day, release builds, full logcat captured)
| engine | context-clear workaround | outcome |
|---|---|---|
#189534 base (8a8208292f5) |
off (gated) | crash at ~11 min; crash at ~106 min |
#189534 head (ac8d095b843, local build, BuildId 762f8846...) |
on (verified active) | crash at ~86 min; crash at ~22 min |
| experimental mitigation (below) | on | no crash, zero IMGSRV errors, 10+ hours |
Additional observations:
- 4 job-pool exhaustion bursts landed on the raster thread's
glClear→ all 4 crashed. 1 burst landed on the IO thread (1.io, Impeller texture-upload path) → the driver only logged and the process survived. Whether the process dies depends solely on which call site the failed allocation lands on. - Trigger state: every burst occurred while the app sat idle on a screen with auto-playing content (banner carousel: periodic image decode → IO-thread texture upload + small animation frames). GL mtrack was a normal ~150–250 MB throughout — not memory pressure. An hour of scripted aggressive scrolling + activity transitions never produced a single
IMGSRVerror. - Each decoded image currently costs a
glFenceSync+ IO-threadglFlush(image_decoder_impeller.cc→ContextGLES::AddTrackingFence) plus a raster-threadglWaitSync; combined with Impeller's per-pass submissions this produces a steady stream of small driver kicks whose retirement seems to fall behind in low-load states, slowly filling the pool.
Experimental mitigation (validated on-device)
Two changes, gated to ro.board.platform starting with mt67:
ContextGLES::AddTrackingFencereturnsfalse→ image uploads fall back toWaitUntilCompleted(glFinish) on the IO thread, so uploads retire driver jobs immediately instead of accumulating fences.CommandBufferGLES::OnSubmitCommandscallsglFinishevery 64th submission → periodically drains the queue so the pool never accumulates.
With this build the device has run clean for 10+ hours under the exact reproduction conditions (and heavier), with zero precursor bursts. A production-quality fix would presumably be finer-grained (cap in-flight fences / batch flushes) — happy to test any variant on this device; with the precursor log as a signal, a build can be validated same-day without waiting for crashes.
Device
| Device | OPPO CPH2203 |
| Build fingerprint | OPPO/CPH2203/OP4F43L1:13/TP1A.220905.001/R.236c2bc+24:user/release-keys |
| Android version | 13 (API 33) |
| SoC | MediaTek MT6779 (ro.vendor.mediatek.platform = mt6779, ro.board.platform = mt6779) |
| GPU | Imagination PowerVR Rogue GM9446, OpenGL ES 3.2 build 1.13@5776728 (Vulkan not used → Impeller falls back to the OpenGLES backend) |
| GL driver | libGLESv2_mtk.so, BuildId 5f0230c5c21f5c7f1d1c30e576a5e1fd |
Flutter version (production crashes)
Flutter 3.44.5 • channel stable
Framework • revision f94f4fc76b (2026-07-06)
Engine • hash d3a3293399556a85388faf8c6f0723a7a5597aa8 (revision 83675ed276)
Tools • Dart 3.12.2
Release AOT build (arm64-v8a), default renderer settings. (Reproduction/testing above was done on master 8a8208292f5 and PR #189534.)
Raw backtrace (production occurrence; identical shape in all reproductions)
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
Cause: null pointer dereference
pid: 5460, tid: 8782, name: 1.raster >>> com.<redacted> <<<
backtrace:
#00 pc 000000000019e794 /vendor/lib64/egl/libGLESv2_mtk.so (BuildId: 5f0230c5c21f5c7f1d1c30e576a5e1fd)
#01 pc 00000000000f737c /vendor/lib64/egl/libGLESv2_mtk.so (BuildId: 5f0230c5c21f5c7f1d1c30e576a5e1fd)
#02 pc 00000000000afab4 /vendor/lib64/egl/libGLESv2_mtk.so (BuildId: 5f0230c5c21f5c7f1d1c30e576a5e1fd)
#03 pc 00000000000b0150 /vendor/lib64/egl/libGLESv2_mtk.so (glClear+564) (BuildId: 5f0230c5c21f5c7f1d1c30e576a5e1fd)
#04 pc 00000000008197d8 libflutter.so (BuildId: 9f490a28849fd415f77ad9165383b441bf3cd3bc)
#05 pc 0000000000818a44 libflutter.so
#06 pc 00000000007de65c libflutter.so
#07 pc 00000000007e3ac4 libflutter.so
#08 pc 00000000008d7c3c libflutter.so
#09 pc 0000000000764168 libflutter.so
#10 pc 0000000000852690 libflutter.so
#11 pc 0000000000852084 libflutter.so
#12 pc 0000000000853398 libflutter.so
#13 pc 0000000000852eac libflutter.so
#14 pc 000000000085fba8 libflutter.so
#15 pc 00000000004e9dbc libflutter.so
#16 pc 00000000004edcb0 libflutter.so
#17 pc 000000000001836c /system/lib64/libutils.so (android::Looper::pollInner(int)+1068)
#18 pc 0000000000017ee0 /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+112)
#19 pc 00000000000185e4 /system/lib64/libandroid.so (ALooper_pollOnce+100)
#20 pc 00000000004eddb4 libflutter.so
#21 pc 00000000004ebcfc libflutter.so
#22 pc 00000000004ebb0c libflutter.so
#23 pc 00000000000eb720 libc.so (__pthread_start(void*)+208)
#24 pc 000000000007e2d0 libc.so (__start_thread+64)
Symbolized engine frames
#04 0x8197d8 impeller::EncodeCommandsInReactor(...) render_pass_gles.cc:300
→ GLProc<void(GLbitfield)> glClear proc_table_gles.h:138
#05 0x818a44 impeller::ReactorGLES::ReactOnce() / FlushOps() reactor_gles.cc:293
#06 0x7de65c impeller::Canvas::EndReplay() canvas.cc:2393
#07 0x7e3ac4 impeller::RenderToTarget(...) / FinishRecording() dl_dispatcher.cc:1326
#08 0x8d7c3c flutter::GPUSurfaceGLImpeller::AcquireFrame(...)::$_1 gpu_surface_gl_impeller.cc:119
#09 0x764168 std::function<bool(SurfaceFrame&, DlCanvas*)>::operator()
#10 0x852690 flutter::Rasterizer::DrawToSurfaceUnsafe(...) rasterizer.cc:811
#11 0x852084 flutter::Rasterizer::DrawToSurfaces(...) rasterizer.cc:603
#12 0x853398 flutter::Rasterizer::DoDraw(...) rasterizer.cc:507
#13 0x852eac flutter::Rasterizer::Draw(...) rasterizer.cc:264
#14 0x85fba8 flutter::Shell::OnAnimatorDraw(...)::$_0 shell.cc:1412
#15 0x4e9dbc fml::MessageLoopImpl::FlushTasks(...) message_loop_impl.cc:126
#16 0x4edcb0 fml::MessageLoopAndroid::OnEventFired() message_loop_android.cc:91
Related
- Broaden version checking for mediatek workaround #189534 — extends the clears out the android context after the frame on mediatek devices #187404 workaround gate to this device; tested on-device (local engine build) and does not fix the crash
- Opts mediatek devices on android 10 and earlier into SurfaceTextures #187336 / clears out the android context after the frame on mediatek devices #187404 — same crash signature, but a different mechanism (idle-context race vs. job-pool exhaustion); suggest treating these as separate MediaTek/PowerVR issue families
- Flutter Crashes OpenGL on MediaTek #166248, [Android] ImageReaderSurfaceProducer still fails on Huawei Kirin API31 devices despite fix for #166481 #188560, App crashes when WebView opens over SVG with ColorFilter on MediaTek Android 10 devices #169500 — other MediaTek EGL crashes that may be worth re-triaging with the job-pool signature in mind (
RM_GrowJobPoolin logcat is the discriminator)
Request
- Reconsider the approach in Broaden version checking for mediatek workaround #189534: on this device class the fix direction that works is reducing GL submission pressure (per-upload fence throttling / batching, periodic queue drain), not context clearing. Our experimental mitigation above validates the direction.
- When triaging MediaTek
libGLESv2_mtk.socrashes, check for theRM_GrowJobPool/Failed to allocate Joblogcat precursor to distinguish this family from the clears out the android context after the frame on mediatek devices #187404 race.
We have the device on hand, a reliable reproduction (idle on a screen with auto-playing carousel content; crash in 11–106 min, precursor log visible sooner), and a local engine build setup — we can validate any experimental fix same-day.
Activity
mbcorona commentedon Jul 10, 2026
Hi @heyi1994 , thanks for the detailed report and for providing the logs. Routing to the engine team for further investigation.
reidbaker commentedon Jul 14, 2026
#166248 #187404
reidbaker commentedon Jul 14, 2026
#188560 appears to be similar in pattern. There was a fix for api 29 and below and users are still seeing the error on higher apis. This bug was for huawei devices. I point it out to help the engine team see if there is a more broad issue or if there are related cases that need to be evaluated.
walley892 commentedon Jul 15, 2026
Hi @heyi1994, can you see if the patch in #189534 fixes your issue? I don't have a mediatek device to test on
heyi1994 commentedon Jul 16, 2026
@walley892 Tested your patch on the affected device (CPH2203, mt6779, API 33). Heads-up first: there are no CI artifacts for this PR (draft — engine presubmits never ran), and checking out the PR branch locally silently builds against the base engine (the content-aware hash uses the merge-base for local branches), so I ended up doing a local engine build from your PR HEAD and verifying the libflutter.so BuildId in the crash dump.
Result: the crash still reproduces with the workaround verifiably active (twice, ~86 min and ~22 min in). It turns out the failure mode on this device is driver job-pool exhaustion (RM_GrowJobPool errors in logcat ~0.5s before every crash), not the idle-context race the workaround targets — so broadening the gate can't help. Full test data and analysis posted in the PR; I've also updated the issue body with the findings and a validated mitigation direction. Happy to test any follow-up build same-day — with the precursor log as a signal we don't need to wait for actual crashes.
walley892 commentedon Jul 16, 2026
@heyi1994, this is difficult for us to debug without a minimal reproduction application / similar hardware. It sounds like you've got a fix working locally and a good testing setup - could you file a pull request?
heyi1994 commentedon Jul 17, 2026
@walley892 Done — opened #189643 with the job-pool mitigation validated on the affected device (~16.5h clean vs. crashes within 11–106 min on every other build). Details in the PR description.