- Issue Description:
On iOS 26 and later, a CoreGraphics crash occurs when rendering images using -[UIImage drawInRect:blendMode:alpha:]. Based on the call stack, the crash happens inside CoreGraphics. Under what circumstances does the function upscale_provider_get_bytes_at_position_inner in the stack get called? When attempting to reproduce locally, this code path is never reached even when scaling images.
- Steps to Reproduce:
There are a large number of crash reports in production, but the issue cannot be reproduced locally/offline.
- Expected Results:
-
Explain under what conditions calling -[UIImage drawInRect:blendMode:alpha:] will reach the upscale_provider_get_bytes_at_position_inner logic. Ideally, provide a code example or demo.
-
Provide the root cause of the crash and a workaround/mitigation.
- Current Behavior:
Calling -[UIImage drawInRect:blendMode:alpha:] causes intermittent crashes in production.
- Xcode Version Used:
Xcode Version 26.0 (17A324)
Thanks for the detailed report, including the crash symbol.
The short version: this is a memory-lifetime problem, not image corruption. CoreGraphics faults while reading the image's decoded pixels during the upscaling drawInRect:. That backing memory is no longer valid at the moment of the draw. The fault is a bad-address access (EXC_BAD_ACCESS), which means the backing is gone, not that its pixel contents are wrong.
I reproduced this exact crash class here, on iPhone and iPad, on iOS 26.5 and on an iOS 27 beta. Making a CGImage's decoded backing invalid, by freeing or unmapping it, then drawing it upscaled, faults in that same CoreGraphics source-read path. The signature matches yours, and CoreGraphics labels the fault in the backtrace as the backing not being readable.
The case to look at is images whose pixel memory your code, or a library, owns and can free. Examples: a CGImage over a CGDataProvider around your own buffer, a CVPixelBuffer or IOSurface-backed image, or output from a custom decoder or image cache. If that memory is freed, reused, or unmapped while a draw is still in progress, you get this fault. If instead these are standard UIImages loaded from your bundle, a file, or Data, the framework manages the backing. Keeping the image object alive is enough.
That timing window is also why it reproduces intermittently in production but not locally. Concurrent drawing widens it, because the backing can be released on one thread while another is still drawing.
The crash does not happen as long as the image, and any backing memory you or a library own, stay valid for the full duration of every draw. To confirm this and find where the backing is released:
- Run under the Address Sanitizer, with Malloc Scribble and Guard Malloc enabled, and exercise the image-heavy screens. This usually turns the intermittent crash into a deterministic one, with a backtrace showing where the memory was freed.
- Capture a fully symbolicated crash report. Confirm the exception type and the faulting thread, in particular whether the draw runs on a background thread.
- Look at how the crashing images are created and backed. Pay attention to any built over a
CGDataProvideraround a buffer your code owns, or decoded into memory that can be released or reused.
I would recommend filing a Feedback Assistant report on this. A hard crash inside CoreGraphics on an unreadable image backing is worth a tracked, reproducible report. That holds whether the resolution lands on your side or as a framework robustness improvement. Attach the symbolicated crash reports and the smallest project that reproduces it. If you post the Feedback ID here, I can refer to it.
If you can share a symbolicated crash report, and a note on whether the drawing runs on a background thread, I can help narrow it further.
For reference:
- https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early
- https://developer.apple.com/feedback-assistant/
Please let me know if there are any questions.