Strange Core Data crash with _Unwind_SjLj_Resume after migrating - iphone

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 it
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 :)

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.

Related

What can cause this SIGSEGV error?

I received a crash log that I cannot explain. I have searched around and it appears that the SIGSEGV has something to do with memory. But in my case there is nothing of my own code except for the main.m in the stacktrace. Also it doesn't seem to symbolicate any of the system libraries.
The crash so far only happened on one iPhone. On other phones I haven't been able to reproduce it. Right now I'm completely stuck and don't know where to continue so if anyone has seen something like this before it would be good to hear their problem and resolution.
The crash log:
Incident Identifier: TODO
CrashReporter Key: TODO
Hardware Model: iPhone4,1
OS Version: iPhone OS 6.1.3 (10B329)
Report Version: 104
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x41fd5903
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x3b0b9564 0x3b0b6000 + 13668
1 libobjc.A.dylib 0x3b0bb1d7 0x3b0b6000 + 20951
2 CoreFoundation 0x33396605 0x332d4000 + 796165
3 CoreFoundation 0x3339635d 0x332d4000 + 795485
4 libobjc.A.dylib 0x3b0bea65 0x3b0b6000 + 35429
5 libc++abi.dylib 0x3ab0b07b 0x3ab0a000 + 4219
6 libc++abi.dylib 0x3ab0b114 0x3ab0a000 + 4372
7 libc++abi.dylib 0x3ab0c599 0x3ab0a000 + 9625
8 libobjc.A.dylib 0x3b0be9d1 0x3b0b6000 + 35281
9 CoreFoundation 0x332dcf21 0x332d4000 + 36641
10 CoreFoundation 0x332dcd49 0x332d4000 + 36169
11 GraphicsServices 0x36eb52eb 0x36eb0000 + 21227
12 UIKit 0x351f2301 0x3519b000 + 357121
13 Stylbar 0x0007109f main (main.m:21)
Edit 3th of May:
The crash log is sent by a user. I haven't been able to reproduce the issue myself unfortunately, which is why it's so difficult for me to figure out what went wrong with just this crash log.
It appeared to have happened about 15 times in a row for the same user when opening a certain view controller. The view controller does several calls to a server to load a post, comments and images and profile pictures. All the code that's executed when this view controller is opened is probably over 2000 lines of code (excluding the RestKit and SBWebImage libraries that are used within this code). Posting that code here wouldn't help anyone I'm afraid.
The most simple and useful way to spend your time hunting for the cause of the crash is to look at your code and focus on places where UIKit has a delegate that points back into your code. For example, I found that the most common place this sort of thing would show up was in UITableView. The reason these problems are so hard to track down is that they might only happen in a low memory situation or in some uncommon UI condition that is very hard to reproduce. It is better to just do a code review and make sure that delegate that are set to point to your classes are set back to nil in your own object destructors. If you have many developers, it is often better to work on some higher level abstractions like a generic table and cell class that is used throughout the project than to have every developer coding up a UITableView and making mistakes like forgetting to nil out the delegate that are very difficult to find.
SIGSEGV is a problem the occurs when your application tries to access an address of memory that doesn't exists or some address where is already reserved to another program. I have the same issue with an application right now but I have to review my code to figure it out better. One clue for this kind of problem could be something equivalent to this (found in wikipedia):
#include <stdlib.h>
int main(void)
{
char p = NULL; / p is a pointer to char that initializes poiting to "nowhere"*/
* p = 'x'; /* Tries to save the char 'x' in 'no address'*/
return 0;
}
I hope this can help someone.

Core Data lightweight migration crashes after App update

Two days ago I released the App. According to feedback on AppStore and crash reports from itunesconnect there are a lot of crashes on launch. But not 100% users suffered, only 30% maybe.
I've read the crash logs and saw a problem. It's crashing on DB migration process. I use lightweight migration of database.
Usually I add new datamodel version very carefully. Even before each release I install a previous version of the App, use it for some time and only then I install the latest version above it. So was this time.
I looked through two datamodels (previous and present). Were added:
1) New entities (it's OK for lightweight migration)
2) New fields inside existing entities. All they are optional. (OK for lightweight migration)
3) One new field in existing entity which I made optional AND indexed. (OK?)
None of existing fields and entities were renamed.
What I did wrong?
Stack trace:
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x352f439c pread + 20
1 libsqlite3.dylib 0x30d2d632 unixRead
2 libsqlite3.dylib 0x30d4221a readDbPage
3 libsqlite3.dylib 0x30d41156 sqlite3PagerAcquire
4 libsqlite3.dylib 0x30d583be moveToChild
5 libsqlite3.dylib 0x30d8e0e8 moveToLeftmost
6 libsqlite3.dylib 0x30d59582 sqlite3BtreeNext
7 libsqlite3.dylib 0x30d54328 sqlite3VdbeExec
8 libsqlite3.dylib 0x30d4f6c2 sqlite3_step
9 CoreData 0x329e8e2e _execute
10 CoreData 0x329e8d64 -[NSSQLiteConnection execute]
11 CoreData 0x32a8bd54 -[NSSQLConnection prepareAndExecuteSQLStatement:]
12 CoreData 0x32add63c -[_NSSQLiteStoreMigrator performMigration:]
13 CoreData 0x32ad42b8 -[NSSQLiteInPlaceMigrationManager migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:]
14 CoreData 0x32a79c02 -[NSMigrationManager migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:]
15 CoreData 0x32ac5bf4 -[NSStoreMigrationPolicy(InternalMethods) migrateStoreAtURL:toURL:storeType:options:withManager:error:]
16 CoreData 0x32ac519c -[NSStoreMigrationPolicy migrateStoreAtURL:withManager:metadata:options:error:]
17 CoreData 0x32ac6b58 -[NSStoreMigrationPolicy(InternalMethods) _gatherDataAndPerformMigration:]
Any chance that those users were more than one .xcversion back? Core Data will not "chain" your upgrades for you. So if you have V1, V2, and V3, and V3 becomes the current version, anyone at V1 will not be upgradable. It is possible to add in your own code that helps "step it through" V1 to V2, then V2 to V3. I believe Marcus Zarra's "Core Data" book had example code that does that.
If this was V3 of the data model, you need to also include the V1 and V2 xcdatamodel with the shipped app, in case some of your users are still on V1 and never upgraded to V2. It kind of sounds like you had a V1 data model, but didn't include it - but I'm not sure, you may simply be talking about other apps where you've done this.
Additionally, you'll notice that Xcode does not manage an ordered list of data models, you can only choose which one is the current one. It cannot automatically upgrade V1->...->Vm->Vn, because it doesn't know anything about the order between old versions, simply that they need to become Vn to work. Try poking around in the xcdatamodeld package with a text editor.
If you're relying solely on behavior provided by Core Data, all of your prior versions must be able to directly migrate to the latest, whether that is inferred mapping models, or by you including explicit mapping models: from V1->Vn, V2->Vn, ..., Vm->Vn. That's why some people write their own code to manage this.
I believe this is exactly what Scott described in his answer.
During development of our app, we created ~6 versions of the data model (we took all but the latest out before shipping v1 to the App Store). I found it very helpful to write unit tests that verified that Core Data could create an inferred mapping model, and that lightweight migration would work.
To do this:
NSURL *sourceURL = /* exercise for reader */, *destinationURL = /* exercise */;
NSManagedObjectModel *source = [[NSManagedObjectModel alloc] initWithContentsOfURL:sourceURL];
NSManagedObjectModel *destination = [[NSManagedObjectModel alloc] initWithContentsOfURL:sourceURL];
NSError *mappingError;
NSMappingModel *inferred = [NSMappingModel inferredMappingModelForSourceModel:source destinationModel:destination error:&mappingError];
At the end of this code block, you can assert that inferred != nil, and if it is nil you can print some helpful information by inspecting mappingError.
You may find this helpful to debug your problem. You might move the repetitive parts into a function that takes two strings, the filename of an old data model, and the filename of the latest.

RestKit ObjectLoader Unrecognized Selector trying to map objects

This issue is specific to RestKit, but I believe the underlying issue is related to registering to notifications. I could really use some help figuring this one out...I seem to be having the same issue appearing multiple times:
An NSInvalidArguementException coming from
serviceDidBecomeUnavailableNotification within RKClient. The action
is calling from __NSMallocBlock__, __NSCFString, __NSCFArray, NSURL,
and UICFFont... obviously the delegate is not being set correctly.
It is ONLY in my requests using RKObjectMapping to map the response to
my model classes. I've noticed the objectLoader has
isResponseMappable and checks [self.response isServiceUnavailable] -
which then posts a RKServiceDidBecomeUnavailableNotification. This
seems to be where my issue is coming from. The only place I see
isResponseMappable being called is within didFinishLoad:(RKResponse*)response.
Here's an example stack trace, I thought this could be very beneficial:
Error Message:
NSInvalidArgumentException: -[__NSMallocBlock__
serviceDidBecomeUnavailableNotification:]: unrecognized selector sent
to instance 0xee168b0
CoreFoundation:2:in `0x37d4dacb -[NSObject doesNotRecognizeSelector:]
+ 174'
CoreFoundation:3:in `0x37d4c945 ___forwarding___ + 300'
CoreFoundation:4:in `0x37ca7680 _CF_forwarding_prep_0 + 48'
Foundation:5:in `0x31c6f50f __57-[NSNotificationCenter
addObserver:selector:name:object:]_block_invoke_0 + 18'
CoreFoundation:6:in `0x37d16577 ___CFXNotificationPost_block_invoke_0
+ 70'
CoreFoundation:7:in `0x37ca20cf _CFXNotificationPost + 1406'
Foundation:8:in `0x31be33fb -[NSNotificationCenter
postNotificationName:object:userInfo:] + 66'
Foundation:9:in `0x31be4c2b -[NSNotificationCenter
postNotificationName:object:] + 30'
MyApp:10:in `0x000d2157 -[RKObjectLoader isResponseMappable] + 114'
MyApp:11:in `0x000d2b83 -[RKObjectLoader didFinishLoad:] + 418'
MyApp:12:in `0x000cb151 -[RKResponse connectionDidFinishLoading:] +
36'
Foundation:13:in `0x31ca6c39 __65-[NSURLConnectionInternal
_withConnectionAndDelegate:onlyActive:]_block_invoke_0 + 16'
Foundation:14:in `0x31bfe6e9 -[NSURLConnectionInternalConnection
invokeForDelegate:] + 28'
If anyone has any helpful tips, ideas, or suggestions on how to debug this, it would be greatly appreciated! I've been dealing with this for two weeks and am only seeing it in deployed apps (cannot replicate the issue) so any insight is better than none! Cheers!
Check whether you have add all the frame works recommended for RestKit, in your project
1. **CFNetwork.framework**
1. **CoreData.framework**
1. **MobileCoreServices.framework**
1. **SystemConfiguration.framework**
1. **libxml2.dylib**
Just incase any others fall onto this solution, the approach I took was:
Completely remove RestKit from my existing project. I then downloaded the master branch of RestKit, reintegrated into my project (there were some deprecated methods, less necessary frameworks, and refactored classes, but all in all pretty simple). I will be releasing this version with the new RestKit within the next week or so, and HOPE to not see this issue arising again.:)
If I do have this issue, I will come back and modify my answer with a reason for why it's still happening.

iTunesConnect crashlog is partially symbolicated; does not show line numbers

The crashlog on iTunesConnect for my XCode 3.2.5-built application shows method names, but not line numbers. For example, in the abridged crash report I've pasted in below, it shows this:
0x000f5ef8 -[MyTableViewController dealloc] + 120
There are two things here that are puzzling me, upon which I'd appreciate some insight. The first is why the raw .crash file coming from iTunesConnect is already partially symbolized: it shows the class and method name, but not the source code file and line number. I would expect the raw iTunesConnect crashlog to show just the hexidecimal addresses. As I understand it, only once I download the crash log onto my local system and explicitly bind it using the appropriate tool (XCode Organizer, symbolicatecrash, atos, gdb x/i command, etc) and to the exact application binary and dSYM files (those having the matching UUID), will I see the full symbols of class, method, source code file, and line number. Even when I download and view the crashlog on a Windows box, it appears partially symbolized. I am concerned that my distribution binary must be including some debug symbols in order for this information to show up in the raw crashlog, despite having "Strip Linked Project" set in its Distribution target settings. Any insight here would be great.
The second thing that is perplexing me, and is of more immediate concern to me in fixing this high-profile crash, is this business of the offset. I've very carefully located the dSYM and application binary with the matching UUID, put them in my home directory so they can be found by Spotlight et al, and no matter what I do, I am unable to convert that offset [MyTableViewController dealloc] + 120 to a source code file (which is known to me to be MyTableViewController.m) and a line number. I have tried the following tricks with the raw iTunesConnect .crash file:
XCode Organizer: its "symbolication" affects no changes to the crashlog -- it's the same.
symbolicatecrash: It doesn't really complain about anything in verbose mode, and the output crashlog is the same
gdb: Using the same gdb and -arch setting that XCode 3.2.5 uses for producing the distribution build, and loading in the matching application binary and dSYM symbols per this post, gdb 'x/i' and 'info line *' commands tells me that [MyTableViewController dealloc] + 120 corresponds to a totally unrelated piece of our codebase in a completely different file -- a .h file, even! Wild goose chase.
Something is not right here. Even despite ensuring the exact same UUID across the crash report, the application binary, and the dSYM file ... none of these tools can yield an actual line number, and doing it the low-level way sends me on a wild goose chase. Knowing the exact line number is critical to fixing this, because we are unable to reproduce this crash in-house so we're flying blind here. This looks to be a simple over-released object, but it's not clear which exact object it is, and we're unable to tell from context. I'm wondering if there is some misappropriated XCode build setting that is somehow breaking the symbolication process.
Thanks for your time!
What follows is the abridged raw .crash log from iTunesConnect.
Incident Identifier: 09EAE058-7D55-4AE5-947A-17280FB0211A
Hardware Model: iPhone3,1
Process: MyApp [1895]
Path: /var/mobile/Applications/B4B872EF-CB0D-41D7-A7B5-435ADE479D0A/MyApp.app/MyApp
Identifier: MyApp
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2011-01-24 14:06:32.941 -0500
OS Version: iPhone OS 4.2.1 (8C148)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0xd0000000
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x33479466 objc_msgSend + 18
1 MyApp 0x000f5ef8 -[MyTableViewController dealloc] + 120
2 CoreFoundation 0x33a26f74 -[NSObject(NSObject) release]
3 libobjc.A.dylib 0x3347a812 objc_setProperty
4 UIKit 0x320bb4a0 -[UINavigationController setDisappearingViewController:]
5 UIKit 0x320bb478 -[UINavigationController _clearLastOperation]
xx SNIP xx
23 MyApp 0x00014eac main + 36
24 MyApp 0x0000b324 start + 44
XX SNIP xx
Binary Images:
0x1000 - 0x1e3fff +MyApp armv7 <5570f8eee3bc11647732c12f96fe9553> /var/mobile/Applications/B4B872EF-CB0D-41D7-A7B5-435ADE479D0A/MyApp.app/MyApp
I've experienced similar issues with releasing object that weren't retained or that were in an autorelease pool thereby getting released twice. More often than not I'll get a crash for a location that is inside the framework/iOS but was caused from my lack of proper memory management. I'm not saying this IS happening here, but just is something I've experienced when a similar error has presented itself.

My own (new) class not found after xcode update

I'm developing iphone app. Yesterday I updated my xcode to to newest version and clean build folders (deleted it), then created new class (nothing special):
#interface EnemyFactory : NSObject {
}
+(Enemy *)properReferenceForName: (NSString *) name;
#end
Implementation is trivial and not important. What is happening now:
I've got sth like this:
Enemy *tempEnemy = [EnemyFactory properReferenceForName:#"enemyname"];
But code never reaches function properReferenceForName. I've got EXC_BAD_ACCESS with stack like this:
0 0x02a95e2b in realizeClass
1 0x02a96dad in _class_getNonMetaClass
2 0x02a90eb0 in _class_initialize
3 0x02a961f6 in prepareForMethodLookup
4 0x02a8f6c9 in lookUpMethod
5 0x02a8f836 in _class_lookupMethodAndLoadCache
6 0x02a9dad3 in objc_msgSend
7 0x0000595d in -[GameLayer newEnemy:] at GameLayer.m:368
Before update. Xcode gives no warning or error. Symbols are declared.
What is interesting though is that: everything goes fine, when I debug step by step whole invocation...
I'm stuck with it for 8 hours.
Update 1:
[[EnemyFactory alloc] init] throws the same error
Update 2:
When I do this:
[EnemyFactory alloc] in some master class during initialization everything goes in flying colours.
Take a look at GameLayer.m line 368 something to do with [GameLayer newEnemy:]. I don't see anything wrong with the code you posted.
If the code is never reaching your class method, the problem is where the stack trace starts, i.e. [GameLayer newEnemy:]
Look for objects that you may need to retain but are not retaining within the newEnemy method.