Alamofire / AlamofireImage

AlamofireImage is an image component library for Alamofire
MIT License
3.99k stars 523 forks source link

UIImage.af_inflate(): Failed to grow buffer crash #332

Open DarrenAndes opened 6 years ago

DarrenAndes commented 6 years ago

Alamofire Environment

Alamofire version: Alamofire (4.7.3), AlamofireImage (3.4.1) Xcode version: 10.0 Swift version: 4.0 Platform(s) running AlamofireImage: iOS macOS version running Xcode: 10.14

I have been receiving numerous crash reports from iOS 12 users only with the latest version of AlamofireImage. I am not sure if this is an issue caused by iOS 12 or a change to AlamofireImage itself.

Unfortunately, I don't know more information than the crash info below so I cannot recreate the cause.

alamofire_crash
fespinoza commented 6 years ago

on our app we got the same crash... it's not that frequent 3 times so far, and with iPhones 6s exclusively (at least for now)

rivsat commented 6 years ago

Our app in production too is getting this crash sporadically. iOS versions: 10, 11

Crashlytics report says:- screen shot 2018-10-30 at 10 06 05 am

There are no specific steps to reproduce it, but from the report it seems that the app runs out of memory and hence is killed by iOS.

TIA

jshier commented 6 years ago

Thanks for the reports! I think this issue has been around for a while and I'm pretty sure the only fix is to disable manual image inflation, as apps can't always control the size of images they're downloading, and apparently the underlying API can fail to claim memory. We'll investigate our options.

ghost commented 5 years ago

Hi @jshier, do you have anymore updates on this? Our app has been receiving a lot of these crashes and our users have escalated. Reproducing it has been a problem since there's no clear repro steps. Same call stack and it's been primarily on iOS 12.

cnoon commented 5 years ago

Hey everyone,

@jshier is on point here as the core issue is inflating images with extremely large sizes which can run your app out of memory. We do have a temporary workaround, but a proper solution here is going to be much more involved in changing the way we force decompression on compressed images.

What you can do right now is one of the following:

Option 1 - Disabling Inflation Entirely

UIImageView.af_sharedImageDownloader.imageResponseSerializer = DataRequest.imageResponseSerializer(inflateResponseImage: false)

This will essentially disable image inflation for all UIImageView instances throughout your app that use the af_setImage APIs.

A better, more focused approach would be to disable image inflation only on image views that can render images of an unknown size. One way you could do this is as follows:

Option 2 - Disabling Inflation Per UIImageView

let downloader = ImageDownloader()
downloader.imageResponseSerializer = DataRequest.imageResponseSerializer(inflateResponseImage: false)

let imageView = UIImageView()
imageView.af_imageDownloader = downloader

Long Term Solution

A longer term solution would be for us to figure out how to resolve the memory allocation issue in the low-level Apple APIs we're calling to force the inflation. This will require quite a bit of work on our part and unfortunately we do not have the bandwidth at the moment to take this on. We're currently working to complete the Alamofire 5 release. Once that is complete, this AFI will be first on our list to get resolved.

Cheers. 🍻

iosdevben commented 5 years ago

Has there been any progress on this issue?

jshier commented 5 years ago

@iosdevben No. Given this is an issue within the memory allocation routines of CoreGraphics / CoreFoundation, it's hard to investigate, and we haven't had much time with the pending release of Alamofire 5. I'm attending WWDC, so I'll be speaking to Apple engineers about how we can be safer here or alternate approaches to inflating images asynchronously.

For anyone seeing this crash, filing an Apple bug and posting the bug number can help us get Apple to look at it.

kaushlendrapal commented 5 years ago

Facing same crash in production, any permanent workaround on this issue.

iosdevben commented 5 years ago

Hi @jshier, did you get any advice from the Apple engineers at WWDC on how to resolve this?

mickyzinho commented 5 years ago

We tried option 2 from cnoon's suggestions, but that lead to a follow-up issue (See crash log below). Any idea what could be causing this?

Thread 13 Crashed:
0   libswiftCore.dylib                   0x000000018e240bc0 0x18e033000 + 2153408
1   libswiftCore.dylib                   0x000000018e05c310 0x18e033000 + 168720
2   Alamofire                            0x00000001011c4dd4 Alamofire.SessionDelegate.urlSession(_: __C.NSURLSession, dataTask: __C.NSURLSessionDataTask, didReceive: Foundation.Data) -> () (SessionDelegate.swift:214)
3   Alamofire                            0x00000001011c4e54 @objc Alamofire.SessionDelegate.urlSession(_: __C.NSURLSession, dataTask: __C.NSURLSessionDataTask, didReceive: Foundation.Data) -> () (<compiler-generated>:0)
jshier commented 5 years ago

@mickyzinho That doesn't seem related to this issue.

@iosdevben I was unable to speak to anyone about this issue, unfortunately.

It would interesting to see if anyone is seeing this crash on iOS 13. Perhaps this was fixed during that release?

treeba commented 5 years ago

@jshier This issue is definitely still happening on iOS 13 unfortunately.

Screenshot 2019-11-11 at 08 45 49
wolfAle commented 5 years ago

Hi guys,

same here, got one on production (luckily only one). Report says "RAM free: 53.77 MB", most likely that's the reason behind it. I'll try to put in place the workaround you suggest.

Screenshot 2019-11-30 at 12 15 24

Alessandro

wolfAle commented 4 years ago

Hi guys,

any news on this? I'm having a bunch of crashes on prod because of this. It happens on all sort of devices with always more than 50 mb of Ram free. Furthermore it doesn't seem related with a runtime downloaded image but while setting an image from the bundle; the crash log contains: CoreUI: deallocating _CUIInternalLinkRendition 60760 /System/Library/CoreServices/CoreGlyphs.bundle/Assets.car Can't be sure if it's always the same image or nor tho.

Screenshot 2020-02-14 at 15 41 52

Thanks, Alessandro

cnoon commented 4 years ago

The proper solution here is to rebuild the inflation logic to rasterize the image which will do two things: 1) decompress the original data and 2) redraw the image in a pixel format optimized to go to screen. Right now we're taking a shortcut to simply decompress the original data. However, I'm not entirely sure if the proper solution would solve your issue. If you load an image that is going to run your application out of memory, then you can't load the image that way.

As a temporary workaround, you can disable the inflation a few different ways. I've updated the main AFI usages to support a custom ImageResponseSerializer so you can disable image inflation per request.

let imageView = UIImageView()

imageView.af_setImage(
    withURL: url,
    serializer: ImageResponseSerializer(imageScale: 4.0, inflateResponseImage: false)
)

You can also do this by setting a custom ImageResponseSerializer on the ImageDownloader instance used by UIImageView.

ImageDownloader.default.imageResponseSerializer = ImageResponseSerializer(inflateResponseImage: false)

However, I'm not entirely sure this will solve your issue, but just change the stack trace. If you try to load an image that is large than you app can handle, it's going to crash regardless. It just won't crash anymore in our inflation logic, but will crash when trying to decompress the data as part of the draw pipeline.

If you do need to blindly load super large images, then you need to load them in a much safer way than we do with AFI. See this Stack Overflow thread for some good information on how to do this along with a sample app from Apple.

Just for full transparency, this is not an issue we will solve any time soon. We are focusing on getting the AFI 4.0.0 release out, and then will focus entirely on some additional large new features going into Alamofire 5.x. Once we address all of those, we may circle back to AFI with a large rework of all the functionality. However, this will not be anytime soon. Cheers all.

sems commented 1 year ago

For a couple of weeks, this issue is starting to pop up in our app as well. This is strange because the app does not support iOS 13 anymore. Where some previous comments pointed towards.