Looped, scaled animated GIFs will eventually crash SFSafariViewController and the host app

Originator:james.reggio
Number:rdar://23706923 Date Originated:12/01/2015
Status:Fixed Resolved:Fixed in iOS 10.0.1
Product:iOS SDK Product Version:iOS 9.1 (13B137)
Classification:Crash/Hang/Data Loss Reproducible:Sometimes
 
[Want to discuss? Get in touch with me @jamesreggio.]

There appears to be a memory leak in the ImageIO libraries for scaling animated GIFs. (A Google search for "ImageIO_GIF_Data" will turn up several complaints and workarounds for unbounded memory consumption for scaled, looped GIFs.) SFSafariViewController appears susceptible to this problem when viewing a webpage that has looped, high-framerate animated GIFs that are being scaled via CSS.

Due to the problems described in Radar #23706636, this memory leak will eventually crash the remote SFSafariViewController process, which in turn will crash the host app.

Steps to Reproduce:
1. Open and interact with a number of apps on a *physical device* in order to create memory pressure. (e.g., open and use Maps, Facebook, Uber, etc. for a couple of minutes.)
2. Open the app referenced below.
3. Tap the 'Bugs' tab bar item.
4. Tap the 'Animated GIF OOM Crash (Bloomberg)' button.
5. Scroll through the page to cause all three animated instructional GIFs to load.
6. Leave the viewport over one of the three instructional GIFs.
7. Wait a couple minutes for the leak to exhaust available memory.

Expected Results:
No memory leak should exist, so the page should always work.

Actual Results:
The host app terminates.

Version:
iOS 9.1 (13B137)

Notes:
The sample project is available on GitHub here:
https://github.com/jamesreggio/SFSafariViewControllerPlayground

It is somewhat difficult to reproduce this issue because it depends upon the presence of significant memory pressure on the device. (The crash doesn't reproduce on a simulator because simulators are not subject to the same memory limitations.)

However, it is relatively easy to see the leak using Instruments. Simply attach Instruments to the SafariViewService (or com.apple.WebKit.WebContent) process and navigate to the problematic page. You'll see an ever-increasingly growth in allocations made by the 'ImageIO_GIF_Data' method.)

Strangely, in October 2015, I was able to attach Instruments to these processes remotely, but in November 2015, I am no longer able to attach to these processes. (I receive a 'Unable to attach to task; port invalid' error.) However, I'm sure you'll be able to side-step whatever limitations I'm encountering as I attempt to debug an Apple-distributed binary.

Configuration:
iPhone 6 on iOS 9.1 (13B137)

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!