Product: ArcGIS Maps SDK for Swift
Affected version: 200.8.2, via Swift Package Manager
Potentially fixed / not reproduced so far: 300.0.0, still soaking
OS/runtime: iOS/iPadOS 26-era runtime, where Apple's xzone malloc allocator turns latent heap corruption into allocator aborts
App context: production iPad/iPhone forestry field app using MapView, LocationDisplay, and a CustomLocationDataSource / custom location provider. The custom provider was introduced to support external GPS receivers, but the crash does not require an external receiver. It also happens when the custom provider forwards the device's own GPS fixes.
Current summary
We are seeing heap corruption / invalid-free crashes in an app using a custom ArcGIS location provider on ArcGIS Maps SDK for Swift 200.8.2.
The strongest evidence now points to a lifetime or threading race in the custom location pipeline when both location updates and heading updates are delivered into the SDK for the same GPS stream.
With malloc debugging enabled, the clearest crash was caught in the heading path:
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at a scribble-patterned pointer
Thread: com.apple.root.default-qos.cooperative
libswift_Concurrency completeTaskWithClosure
ArcGIS Swift layer
CoreArcGIS RT_LocationDataSource_updateHeading + 124
CoreArcGIS internal frames
SIGSEGV
In another run with auto-pan completely off, unmodified code still crashed after about 12 minutes, this time inside or near:
CoreArcGIS RT_LocationDataSource_updateLocation
That makes the current working theory:
There is a race in 200.8.x when a CustomLocationDataSource feeds both location and heading updates into the SDK. One async update can outlive or race internal location-display state used by the other update, so an in-flight update dereferences freed memory. In production this often appears later as unrelated allocator crashes rather than at the original corrupting frame.
Production symptoms
Before we had a precise simulator repro, field crashes looked like a family of malloc aborts with different victim stacks:
_xzm_free_abort
_xzm_xzone_malloc_freelist_outlined
Victim stacks included:
- CoreArcGIS request teardown / pplx continuation destruction
- CoreArcGIS vector-tile request task allocation
- Swift allocation on the main thread
- CFNetwork CacheDB write
- CGBitmapContextCreate / map rendering related work
We originally suspected request cancellation / vector-tile request teardown under network churn. That may still be part of the workload that makes the app busy, but based on the later malloc-debugging repro, we now believe those request-teardown allocator crashes are likely downstream victims of earlier heap corruption in the custom location update path.
Reproduction setup
We can reproduce on the iOS Simulator using an iOS/iPadOS 26-era runtime on macOS 26, with the same stricter xzone allocator behavior seen on affected devices.
The app is our production app built against ArcGIS Maps SDK for Swift 200.8.2.
Map workload:
- MapView with multiple operational layers
- ArcGIS vector-tile layers, tiled layers, and feature layers
- LocationDisplay showing the custom location provider
- Track recording enabled
- Simulated movement at about machine speed
- The app persists a track segment every 15 to 25 seconds
- Each track save refreshes the track feature layer in our app, adding layer/request churn
Location workload:
- Simulated GPS at about 1 Hz
- xcrun simctl location start --speed=3 --interval=1
- Zig-zag route across a forestry work area
- About 130 waypoints
- Random jitter of about +/- 4 m to mimic real GPS noise
- In the unmodified 200.8.2 build, each GPS fix effectively feeds both a location update and a heading/course update into the custom ArcGIS location data source path
Network workload:
- The crash can be reproduced without a perfectly stable office-Wi-Fi environment
- To match field conditions, we also run a pf/dummynet script that alternates degraded and normal network conditions every few seconds
- Degraded profile: low bandwidth, high latency, and packet loss
Observed repro timing:
- Original allocator-victim crashes reproduced after tens of minutes to about 70 minutes
- With malloc debugging, the more precise RT_LocationDataSource_updateHeading failure was captured much faster
- With auto-pan completely off, unmodified 200.8.2 still crashed after about 12 minutes, this time in the location update path rather than the heading path
Workaround we validated on 200.8.2
We stopped feeding heading updates to ArcGIS unless they are actually needed for compass navigation.
Specifically:
- The custom provider still supplies location updates at about 1 Hz
- The location object still contains course information, so the location symbol can still rotate correctly
- The separate heading stream is suppressed unless LocationDisplay.autoPanMode == .compassNavigation
- When compass navigation is active, we throttle/drop heading deltas smaller than about 2 degrees
- In normal track recording with .recenter follow, this means zero calls into the separate heading-update path
This workaround has so far removed the repro on 200.8.2 in our main field scenario.
Follow-up observation: after we suppressed heading updates, the same rig ran for 5.5+ hours without the crash, with locations still flowing at about 1 Hz. That suggests the dangerous part is not location updates alone, but feeding both location and heading updates into the custom location pipeline.
ArcGIS 300.0.0 A/B test
We are now running a separate A/B test:
- Simulator A: ArcGIS Maps SDK for Swift 300.0.0, without the heading-suppression workaround
- Simulator B: ArcGIS Maps SDK for Swift 200.8.2, with the heading-suppression workaround
- Same app workflow
- Same track-recording case
- Same simulated GPS route
- Same network-flap stress
So far, the 300.0.0 build has not reproduced the crash without the workaround.
This is still a preliminary result. We are not treating it as conclusive until it has soaked longer. But if it continues to hold, our preferred long-term fix will likely be to upgrade to 300.0.0 and remove the 200.8.2 workaround instead of keeping the workaround permanently.
Questions for Esri
1. Is there a known 200.8.x issue fixed in 300.0.0 related to CustomLocationDataSource, RT_LocationDataSource_updateHeading, or RT_LocationDataSource_updateLocation?
2. Is it supported/recommended for a custom location provider to omit the separate heading stream and provide course only in the location object, unless compass navigation is active?
3. Are custom providers expected to serialize location and heading delivery in a specific way?
4. Is it expected that location and heading updates may be processed concurrently inside the SDK?
5. If 300.0.0 contains relevant lifecycle/threading changes in the location pipeline, can you confirm whether upgrading is the recommended fix for this class of crash?
We can provide raw Crashlytics reports, CoreArcGIS frame offsets, and the repro recipe if that helps.
Repro
Attached is a minimal SwiftUI repro project using ArcGIS Maps SDK for Swift 200.8.2. In our simulator testing, the custom-location stress scenario eventually produced a memory-safety termination under checked allocations: RBSProcessExitStatus domain:mte-fail(37) code:262.