png_error inside UIImagePNGRepresentation only on iOS 5.1+
Asked Answered
E

5

10

We are experiencing a strange crash where UIImagePNGRepresentation() is sometimes causing png_error calls. We have been unable to reproduce this error on any of our devices in house.

Here is an example of the stack trace from one of our HockeyApp crash logs:

Thread 0 Crashed:
0   libsystem_kernel.dylib         0x3167132c __pthread_kill + 8
1   libsystem_c.dylib              0x33d6729f abort + 94
2   ImageIO                        0x346c38bf png_error + 114
3   ImageIO                        0x346c2fe3 png_write_end + 46
4   ImageIO                        0x346bf069 writeOnePng + 2260
5   ImageIO                        0x346be78b _CGImagePluginWritePNG + 82
6   ImageIO                        0x346be6fd CGImageDestinationFinalize + 132
7   UIKit                          0x31346e23 UIImagePNGRepresentation + 274

We have only been seeing this crash logs on devices running iOS 5.1+ and above. We've actually been getting crashes from iOS 6 as well so this bug has not yet been fixed.

I wrote a test app that downloads over 16,000 of the possible images that our app can display and all of them were able to be downloaded and saved to disk with no problems. Some responses to this gist imply that this issue could be caused by corrupted images but seeing as how I downloaded over 16,000 images and never once had an issue I don't think this could be the case.

The latest hypothesis I am working on is that somehow the data being downloaded is corrupted and therefore a corrupted UIImage is being created. However all attempts to create a corrupted UIImage have failed. Apple seems to have created a robust constructor for UIImage such that anything that I pass in which is invalid results in a nil being returned from the constructor.

Has anyone else experienced anything like this from UIImagePNGRepresentation?

Edik answered 12/9, 2012 at 15:17 Comment(6)
Do you know which device this crash happens on? Is it iPhone, iPod touch or iPad only?Resolvable
We are seeing it on all devices, but primarily iPhone4,1 , iPhone3,1 and iPhone2,1... but I think that's just because of our user base. I haven't normalized by registered devices.Edik
Maybe it's a low-memory error? If you read all the PNGs into memory, malloc() will eventually return 0...Aspect
Good idea – I just created a leaking app to test this, but it just kill -9'd the app.Edik
Have you found a resolution to this? I'm getting a similar error but its slightly different: 3 ImageIO 0x320857c4 _cg_png_error + 84Bowlds
Nope, sorry. We ended up switching to a different image caching library which resolved the problem. It was likely a problem with getting the png representation on a different thread.Edik
G
0

Have you tried testing with different network conditions? 3G or edge instead of just wifi? Try using the Network Link Conditioner to simulate these conditions of slow and lossy networks.

Gibbet answered 17/9, 2012 at 15:44 Comment(3)
I don't see what creating a PNG has to do with network conditions... UIImagePNGRepresentation is only called once the image download has been completed.Edik
Yes, but you could be getting a corrupted or partial image download.Gibbet
In my original post I mentioned that we created corrupted images and tested them, to no avail. Thanks for the suggestion though.Edik
E
0

Are you making ANY UIKit calls from secondary threads? I've seen crashes where UIKit graphic calls on secondary threads work but the main thread crashes at some point later on. There are a few UIKit methods that are ok to use on secondary threads, but not many.

Enthalpy answered 20/9, 2012 at 3:27 Comment(1)
Unfortunately the pkill is on thread 0. We are doing the UIImagePNGRepresentation call on the main thread, which is funny because I was about to move it off so it wouldn't block, but I guess it might make matters worse?Edik
C
0

I've been wrestling with a similar local image corruption problem for a few months in my production app (using UIImageJPEGRepresentation() in my case), and in my case it had nothing to do with downloading the image - but the local storage and rendering.

In my case, the actual user effect of the error was that the image would only partially render; the remainder of the image simply appear gray and corrupt. I am storing and reading from the disk using Core Data (but Core Data was shockingly not my problem).

MY FIX:

I was formerly using this convenience method:

UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

..but on the advice of some other related posts here, I switched to this combination of methods instead:

NSData *resultData = [NSData dataWithContentsOfFile:imagePath];
UIImage *image = [UIImage imageWithData:resultData];

..and it SEEMS to have solved my problem!

MY THEORY

I'm guessing that imageWithContentsOfFile: is, for some reason, worse at handling some non-atomical edge case conditions vs. the pure base NSData calls, and it is for some reason allowing a 'read' to begin before the previous 'write' has completed.

Hope this helps! Good luck.

Coronet answered 25/12, 2012 at 9:46 Comment(1)
I think this may be a different issue than what we're experiencing here. The problem is not with serializing NSData into a UIImage but when a UIImage is serialized into NSData the thread that this is happening on gets a kill signal and since this is happening on the UI thread (which in itself is already a problem) the app dies.Tilefish
F
0

If the call to UIImagePNGRepresentation is inside a loop, i saw a fix on another SO thread which suggests to add sleep(1.0); after the save.

Fireball answered 27/5, 2013 at 7:47 Comment(1)
Unfortunately this is on a web image cache, and could potentially be called hundreds of times a second.Edik
L
0

We had this problem in an app running at scale. It was occurring over 1000 times a day. Using the logging capabilities in Crashlytics we were able to determine exactly which images were causing the crash.

There were about 25 images triggering the crash. We realized that every one of these images had been exported from Photoshop, whereas most of our images had been exported from Illustrator. The images rendered fine in every other program we tried, and we were never able to determine what was "wrong" with them. But we re-exported the images from Illustrator, and our incidence of this crash went to zero.

I realize this doesn't provide root cause but thought it might be helpful to someone else experiencing this issue.

Lamellate answered 18/11, 2013 at 17:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.