Heap corruption occurs when creating Dictionary with double3 value (simd)

Number:rdar://37470003 Date Originated:2/12/2018
Status:Resolved Resolved:3/29/2018
Product:Developer Tools Product Version:Xcode 9.2 (9C40b), Swift 4.0
Classification:Serious Bug Reproducible:Always

We've been encountering a mass amount of heap corruption crashes from certain device types, dating back to November 2017. Unfortunately we haven't payed much attention until it became so frequent recently (more users coming in, more people adopting iOS 11 maybe?).

The crash reports were not meaningful in a way that the crash was coming from all around the code. We started looking at all our concurrent code, or unsafe code, but everything seemed fine.

We are using simd types for vector and matrix operations, especially to make it work with SceneKit without having to think about the types. Types mostly being double3 and double3x3. While investigating the issue, isolating it more and more, we've found out that the problem is always related to reading, or writing double3 typed vectors to, or from a Dictionary.

The crash in our app only happens on iOS 11 only on one of these devices: iPhone 5S, iPhone 6, iPhone 6 Plus, iPhone SE, iPad mini, and iPod touch 6 gen. At least these are the devices involved in the heap corruption incident according to our crash reporting system in place. Does not crash the Simulator (same OS, same device type).

Please note, all the code that is crashing now has been there in our app for a while (long before iOS 11 arrived). We are not in possession of such iOS & device type combo to try to eliminate the possibility that this issue was already present on iOS 10, but as per our crash reports, it never happened on iOS 10, although we still have and support iOS 10 users.

Steps to Reproduce:

After all we managed to isolate the issue to a very simple case:

var x: Int = 0
while x < 100 {
   var dict: [String: double3] = [:]
   dict["vector \(x)"] = double3(Double(1.23456), Double(44.455488), Double(x))
   x += 1

The loop above has a 100 iterations, although most of the times it only takes it about 3-10 rounds to crash. Sometimes it's more. If it does not crash, increase the number of iterations. If you remove the print(), meaning there's no access to the item after it's initialized, it will only crash at a later iteration. Probably the more access to such item in the Dictionary the earlier the crash comes. It barely happened to me that it survived more than 100.

Expected Results:

A 100 Dictionaries, each having one item, a String key and a double3 value printed on the debug console.

Actual Results:

The program crashes after the first few iterations indicating heap corruption with producing a log message like:

malloc: *** error for object {address}: incorrect checksum for freed object - object was probably modified after being freed.

Xcode Version 9.2 (9C40b), Swift 4.0.



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!