Skip to content

[Impeller/GLES] Recurring SIGSEGV in libGLESv2_mtk.so (glClear) on raster thread on MediaTek **Android 13** device — please extend the #187404 workaround beyond API 29 #189190

Description

@heyi1994

[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 IMGSRV error.
  • Each decoded image currently costs a glFenceSync + IO-thread glFlush (image_decoder_impeller.cc → ContextGLES::AddTrackingFence) plus a raster-thread glWaitSync; 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:

  1. ContextGLES::AddTrackingFence returns false → image uploads fall back to WaitUntilCompleted (glFinish) on the IO thread, so uploads retire driver jobs immediately instead of accumulating fences.
  2. CommandBufferGLES::OnSubmitCommands calls glFinish every 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

Request

  1. 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.
  2. When triaging MediaTek libGLESv2_mtk.so crashes, check for the RM_GrowJobPool / Failed to allocate Job logcat 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

  1. added
    c: crashStack traces logged to the console
    platform-androidAndroid applications specifically
    engineflutter/engine related. See also e: labels.
    e: impellerImpeller rendering backend issues and features requests
    fyi-androidFor the attention of Android platform team
    on Jul 10, 2026
  2. mbcorona commented on Jul 10, 2026

    @mbcorona
    Member

    Hi @heyi1994 , thanks for the detailed report and for providing the logs. Routing to the engine team for further investigation.

  3. reidbaker commented on Jul 14, 2026

    @reidbaker
    Member
  4. reidbaker commented on Jul 14, 2026

    @reidbaker
    Member

    #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.

  5. walley892 commented on Jul 15, 2026

    @walley892
    Contributor

    Hi @heyi1994, can you see if the patch in #189534 fixes your issue? I don't have a mediatek device to test on

  6. heyi1994 commented on Jul 16, 2026

    @heyi1994
    Author

    @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.

  7. walley892 commented on Jul 16, 2026

    @walley892
    Contributor

    @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?

  8. heyi1994 commented on Jul 17, 2026

    @heyi1994
    Author

    @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.

  9. added
    P2Important issues not at the top of the work list
    needs repro infoAutomated crash report whose cause isn't yet known
    on Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: crashStack traces logged to the consolee: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.needs repro infoAutomated crash report whose cause isn't yet knownplatform-androidAndroid applications specificallyteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions