Sean Heber Profile picture
I make @Frenzic and @Twitterrific and other stuff for @Iconfactory. President of the galaxy. I'm just this guy, you know? https://t.co/pVgR6I66Mm

Aug 23, 2019, 14 tweets

Earlier this week I tweeted about Core Data crash reports that I haven't been able to figure out. In fact, almost all of Twitterrific's reports were from Core Data. I assumed I was doing something wrong somehow but didn't know how to figure it out since I couldn't reproduce it.

These crash reports have been plaguing me for a long time. Years, probably. I've come to mostly ignore them assuming there was nothing I could do about them. I've asked a few times on Twitter and Googled a bit over that time, but nothing ever turned up.

This week, there was a breakthrough. Specifically, three people used the TestFlight feedback mechanism to report a crash that iOS had reported. They noted the app was in the background at the time. I had long suspected that was the case with this bug, but I was missing something.

Rather than look at the crash reports inside Xcode's Organizer, like I usually do, I happened to download the report attached directly to one of those feedback reports and take a look at it. It matched the typical Core Data crashes I see all the time in Organizer. No surprise.

I was about to close the log in defeat when I noticed that the Termination Reason was something unfamiliar. Xcode's Organizer does not report termination reasons on the crash reports - after all, one would normally assume the reason it was terminated was BECAUSE IT CRASHED, DUH!

Here's the thing - that assumption is totally wrong. iOS routinely terminates apps for all sorts of reasons like using too much memory or taking too long to do background processing or whatever. I don't know why this isn't included in Xcode's Organizer.

Naturally the termination reason in the raw crash log isn't some nice easily human-readable message - no, it's a hex code and a cryptic string that maybe suggests which subsystem is responsible for it. Why make anything easy for the developers, right?!

In this Core Data crash report the termination reason was: Namespace RUNNINGBOARD, Code 0xdead10cc. This was something I could Google. I found a few posts with it, although in many cases this hits were crash reports and no one noted the significance of the termination reason.

I found Tech Note 2151: developer.apple.com/library/archiv… and there it was way at the bottom under Other Exception Types: "The exception code 0xdead10cc indicates that an application has been terminated by the OS because it held on to a file lock or sqlite database lock during suspension."

Holy crap! I've been searching for this for ages and here, finally, is a clue! So I start looking around in the code now that I know what sort of trigger to look for. I find that there were cases where I wasn't asking for more background time before starting certain operations.

What was happening was, the app was sometimes closed while it was still doing some kind of network download and iOS was leaving it running in the background long enough for the network request to finish - but not long enough for the database processing and saving to finish.

Due to incorrectly placed task markers, the background task would be marked done before it had finished saving the database. When things happened in the wrong sequence, iOS would unceremoniously murder the process immediately - making it look like it had crashed inside Core Data.

I spent several days reworking a bunch of really old code to ensure task markers were being created and ended in the proper sequence and to ensure that the task wasn't marked as ended until after the *entire* process was done. Lo and behold, this appears to have worked!

So there you have it - another exciting tale of me doing things wrong for years! Remember kids, I'm a professional!

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling