Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Heap corruption / double free in MapboxCoreMaps when a CarPlay MapView renders while its scene is in the background (11.31.1)

Open
#2,444 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
30/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
ios, swift
Domain
backend, mobile

Research direction

Start with the MapView display state and lifecycle paths described in the report, especially sceneWillDeactivate, sceneDidEnterBackground, reduceMemoryUse(), MetalView.draw, and MapView.updateFromDisplayLink; inspect related issues #2052 and #2195. Reproduce with CarPlay Simulator and Guard Malloc, keeping the hidden map rendering while the scene is in the background. Done means background rendering or skipped frames no longer corrupt memory across the reported cycles.

Written by the indexing model from the issue text.

Description

auto-triaged bug :beetle: p1

Environment

  • Xcode version: 27.0 (27A266a)
  • iOS version: 26.6.2 (reproduced), also seen in the field on 26.6.x, 26.7.1, 27.0
  • Devices affected: iPhone 15 (iPhone16,1) on our test rig; in the field iPhone 15–17 Pro
  • Maps SDK Version: MapboxMaps 11.31.1, MapboxCoreMaps 11.31.1, MapboxCommon 24.31.1 (via mapbox_maps_flutter 2.31.1). Same crashes on 11.20.2 / 24.20.2.

Observed behavior and steps to reproduce

Our app has two MapViews in one process: the phone map (Flutter plugin) and a native MapView inside the CarPlay CPWindow. If the CarPlay MapView keeps rendering while its CPTemplateApplicationScene is in .background (car screen showing CarPlay home, Music or another app), the app crashes with heap corruption inside MapboxCoreMaps as soon as the app comes back from the background, or when the car scene connects. None of our code is on the crashing stack.

Steps (iPhone over USB + CarPlay Simulator):

  1. Create the CarPlay MapView with mapView.displayState = [.foregroundActive, .foregroundInactive, .background].
  2. Connect CarPlay, open the app on the car screen, then switch the car screen to the CarPlay home screen. The scene goes to .background and MapView pauses (connectedScene cleared in sceneWillDeactivate).
  3. Make the hidden map keep drawing: post UIScene.didActivateNotification with the car scene as the object. We did this from a render watchdog after 4 s without frames. On 11.20.2 this step isn't needed: the display link keeps running in the background once .background is allowed.
  4. On the phone, open Settings for ~4 s, then bring the app back. Repeat.
  5. Run with Guard Malloc to catch it right away: xcrun devicectl device process launch -e '{"MallocProbGuard":"1"}' <bundle id>.

Variant: with the app in the background, disconnect and reconnect the car while it shows the home screen. The car scene connects in .background; if the map is nudged into drawing (same notification on the first layout pass), the app crashes within about a second.

Results:

  • Hidden map drawing: 5 of 5 runs crashed within 1–3 cycles.
  • Hidden map left paused: 0 crashes in 75 cycles.
  • Car map visible (scene active) with the phone going to the background and back: 0 in 30.
  • No car connected: 0 in 30.
  • Without Guard Malloc: no crash in 30 cycles in any variant (the corruption is silent there).

Typical messages:

  • BUG IN CLIENT OF LIBMALLOC: free to empty or invalid chunk detected (likely double-free) on com.mapbox.threadpool
  • BUG IN CLIENT OF LIBMALLOC: memory corruption of free block (operator new on a threadpool thread, once on the main thread inside StyleManager::addStyleImage)
  • In the field also Pure virtual function called! in mapbox::common::RunLoop::~RunLoop on the main thread

Faulting frames (MapboxCoreMaps 11.31.1 UUID A6900208-95DF-33BA-9A4B-AF77F668EE78, MapboxCommon 24.31.1 UUID 6A8EDD2C-FA7B-33FF-836E-13F17C762895):

1) _xzm_free_abort < _xzm_free < MapboxCoreMaps +0x588a08 +0x593b54 +0x48bb18 +0xa19c94 +0xa28020 +0xa09cc4 < MapboxCommon +0x1bd218 +0x220d04 +0x1ba624
2) _xzm_free_abort < _xzm_free < MapboxCoreMaps +0x9f6fdc +0xa1b958 +0xa1c0f0 < MapboxCommon +0x220d04 +0x1ba624
   (main thread at the same time: MapboxCoreMaps +0x6eaf70 +0x7b829c +0x79d580 +0x7430ec < MetalView.draw < MapView.updateFromDisplayLink)
3) _xzm_xzone_malloc_freelist_outlined < operator new < MapboxCoreMaps +0xa4f4d8 +0xa4c7e0 +0xa2268c +0xa18a40 +0xa28020 +0xa09cc4 < MapboxCommon +0x220d04
4) main thread: _xzm_xzone_malloc_freelist_outlined < operator new < MapboxCoreMaps StyleManager::addStyleImage (+0x1590a0) +0xef43c < StyleManager.addImage
5) _xzm_free_abort < _xzm_free < MapboxCommon +0x1bd250 +0x220d04 +0x1ba624

The five full Apple crash reports are attached.

Expected behavior

DisplayState.background is a documented option ("allows the map to continue updating while the app is backgrounded"). With it set, the map should either render safely or skip frames when the GPU isn't available. It should never corrupt the heap. A synthetic or real scene activation shouldn't be able to put the renderer into a state that leads to a double free.

Notes / preliminary analysis

  • In production this showed up as about 170 native crashes since we shipped CarPlay, almost all in CarPlay sessions. A build with CarPlay turned off had none. Without Guard Malloc the double free is usually silent and the app dies later somewhere unrelated (a TLS handshake, our own Swift code, Network.framework), so the crashes were spread over many unrelated-looking signatures.
  • In 2 of the 5 reports the main thread was inside MapboxCoreMaps rendering (MetalView.draw ← updateFromDisplayLink) at the moment a threadpool task hit the double free.
  • Two guesses, not verified:
    • sceneDidEnterBackground always calls reduceMemoryUse() (mapboxMap.reduceMemoryUse() + metalView?.releaseDrawables()), even when .background is allowed and the display link keeps running.
    • Rendering in the background means Metal command buffers get rejected (we've seen IOGPUCommandBufferCallbackErrorBackgroundExecutionNotPermitted). v10.20.0 fixed "commit an already committed command buffer" after a failed buffer; maybe a similar path exists in v11.
  • Workaround on our side: we removed .background from the CarPlay MapView's displayState and stopped posting the activation while the car scene is hidden. That made it go away on the rig.
  • Could you symbolicate the offsets above, and confirm whether .background is meant to be safe for a CarPlay MapView? Happy to put together a small sample project or try a debug build if that helps.

Additional links and references

  • Possibly related: #2052 (MapboxCoreMaps crashes with "Pure virtual function called" and heap corruption), #2195 (crash in MetalView.draw, xzone malloc trap).
  • No fix for this in the 11.32.x or 11.33.0-rc.1 release notes as far as we can see.
Dominant language
Swift
Stars
601
Forks
198
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from mapbox/mapbox-maps-ios

All issues in mapbox/mapbox-maps-ios

Similar issues

More Swift issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.