Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange Core Data crash with _Unwind_SjLj_Resume after migrating

I am getting a strange crash from some of my beta testers that I am having trouble with. The symbolicated crash reports indicate that the crash is occurring in the simple allocation of a controller as a singleton, at the init call, but according to the stack trace, it appears that the code I have in init is not actually where the crash is. Here is the relevant code:

1534| + (UA[REDACTED]PlayerController*)sharedInstance
1535| {
1536|     @synchronized(self)
1537|     {
1538|         if (sharedInstance == nil)
1539|     sharedInstance = [[UA[REDACTED]PlayerController alloc] init];
1540|     }
1541|     return sharedInstance;
1542| }

This has never crashed before, and the code has not changed anytime recently. Here is the raised stack trace:

Thread 5:
0   libSystem.B.dylib              0x33bd52d4 __kill + 8
1   libSystem.B.dylib              0x33bd52c4 kill + 4
2   libSystem.B.dylib              0x33bd52b6 raise + 10
3   libSystem.B.dylib              0x33be9d26 __abort + 62
4   libSystem.B.dylib              0x33be9d7e abort + 62
5   libSystem.B.dylib              0x33bd7980 __assert_rtn + 152
6   libgcc_s.1.dylib               0x32acab4e _Unwind_SjLj_Resume + 26
7   [REDACTED]                     0x00060b64 +[UA[REDACTED]PlayerController sharedInstance] (UA[REDACTED]PlayerController.m:1540)
8   [REDACTED]                     0x00063e6c -[UA[REDACTED]PlayerViewController setupControlViews] (UA[REDACTED]PlayerViewController.m:224)
9   [REDACTED]                     0x00062ce0 -[UA[REDACTED]PlayerViewController viewDidLoad] (UA[REDACTED]PlayerViewController.m:268)
10  UIKit                          0x320a0270 -[UIViewController view] + 104
…

Any ideas as to what this cryptic crash is and where it might be coming from?





UPDATE 1
It appears it has to do with core data and migrations. I was able to duplicate it, but the root cause is still unknown. I have some automatic migrations that are in this version, and it appears that while some of the NSManagedObjects can be read, others are throwing this exception, particularly on a NSManagedObjects relationship. It might not be related to the PlayerController at all. Any Core-Data experts have some insight?



UPDATE 2
Here is the call stack of the crash after I have found a way to reproduce italt text
and the relevant code:
if (resultArray && [resultArray count]) {
    for (MixAudio *ma in resultArray) {
        Audio *audio = [ma valueForKey:LOCAL_MIX_AUDIO_AUDIO_KEY];
        if (audio) {
            [returnArray addObject:audio];
    }
}

To help explain what I did to reproduce it, I have to explain the data structure a little. I have Mix and Audio items. Mixes have many Audio, Audio belongs to many Mixes. This is a simple relationship call on the MixAudio objects to get the Audio. Now, this has only been crashing here after I do a database restore to the new version.

Database backups in my setup means zipping up the database to save the data, then unzipping on restore. This crash only happens after the restore process. To make things more complicated, there are 3 database versions with mapping models. Because this process worked for me before the versioning, I feel that something in my versions is causing this crash.

All other data is fine and can be accessed, even saved. Somehow, this single fetch is causing issues. There are no errors or warnings when setting up the persistent store or managed object model. Furthermore, new Mix objects can be created and accessed fine, only older fetches (that were in the DB before the restore) are failing.

If I don't catch the error, the console prints:

Assertion failed: (_Unwind_SjLj_Resume() can't return), function _Unwind_SjLj_Resume, file /SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c, line 326.

Putting a try/catch around the crashing line allows me to inspect the root crash cause:

Error: NSRangeException: *** -[NSMutableArray objectAtIndex:]: index 4294967295 beyond bounds [0 .. 16]

but this makes no sense (to me at least) for a simple valueForKey call. 4294967295 = 2^32-1 which means the index var was probably set to −1 if that helps. I am lost here.





[SOLVED] UPDATE 3
I was right about it being in the versioning :) I reread the section on versioning in Zarra's book and had a major DOH moment. This is the first time I have ever had an app with 3 database versions. I am using Mapping Models in my app and I naively assumed that core data would be able to map from 1-2 using one model, then 2-3 using the next. I literally hit my head when I realized I did not have a 1-3 mapping model. to test it out, I added one quickly and everything is as smooth as butter. Now I just have to go back and use his Progressive Data Migration samples to make my life easier as I go on with more version of this DB.

I am hoping Zarra drives by here and answers something… anything… so I can give him the points for this :)

like image 437
coneybeare Avatar asked Jan 07 '11 14:01

coneybeare


1 Answers

While the OP was able to solve his own question, it is helpful to have a clear understanding of migrations.

When you create a second version of your data model, you need a mapping model from version one to version two.

When you create a third model you need a mapping model from one to two AND a map from one to three.

When you add a fourth model you need the following models:

  • 1-2
  • 1-3
  • 1-4
  • 2-3
  • 2-4

And it gets more progress from there.

like image 95
Marcus S. Zarra Avatar answered Oct 25 '22 17:10

Marcus S. Zarra