App crashes during startup with valueForUndefinedKey error - iphone

During the app startup, I show a table view. Each row shows a managed object's data in some form. One customer is reporting a crash in the app startup. I looked at his crash log and could track down to a place where I use [NSManagedObject valueForKey:] method inside cellForRowAtIndexPath method. The app crashes with [NSManagedObject valueForUndefinedKey:] exception.
How come just one device in a 1000s of devices could get this issue? Running the same version of iOS and the app, I couldn't imitate it in any of my devices. what could have gone wrong?
Last Exception Backtrace:
0 CoreFoundation 0x3549e88f __exceptionPreprocess + 163
1 libobjc.A.dylib 0x368c5259 objc_exception_throw + 33
2 CoreFoundation 0x3549e5c5 -[NSException init] + 1
3 CoreData 0x329d3b23 -[NSManagedObject valueForUndefinedKey:] + 327
4 Foundation 0x312b59d1 _NSGetUsingKeyValueGetter + 125
5 CoreData 0x3298d995 -[NSManagedObject valueForKey:] + 121
6 MyApp 0x0000c513 -[Activity isOn:] (Activity.m:371)
7 MyApp 0x0000beaf -[Activity firstMarkableDate] (Activity.m:163)
8 MyApp 0x0000c0cb -[Activity statusString] (Activity.m:220)
9 MyApp 0x0000bd51 -[Activity statusColor] (Activity.m:139)
10 MyApp 0x00004af1 -[ActivityListViewController tableView:cellForRowAtIndexPath:] (ActivityListViewController.m:418)
11 UIKit 0x3251d0a3 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 547

This may be a memory management issue. See -[Activity isOn:] where it invokes valueForKey:. The object you send valueForKey: is apparently of the wrong class. See where the object is coming from.
The object may get over-released and its memory address may get occupied by an object of a different class which isn't KVO-compliant for trackname key. If that's the case, I would bet that your app gets EXC_BAD_ACCESS even more often.
Why would that happen? NSManagedObjects have many subtleties with regard to their lifetime. They may get deleted in other parts of your app, for example, so you should always expect that and act appropriately.
I hope this will point you in the right direction.

Related

How to know where crash for postNotificationName:object:userInfo

Is there some method to know crash reason in Xcode 4.6?
The crash stack is :
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0xd9f2c061
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x3a74f5aa objc_msgSend + 10
1 Foundation 0x33157599 -[NSNotificationCenter postNotificationName:object:userInfo:] + 73
2 UIKit 0x347830cd -[UIApplication _handleApplicationSuspend:eventInfo:] + 733
3 UIKit 0x346f91e7 -[UIApplication handleEvent:withNewEvent:] + 2459
4 UIKit 0x346f86cd -[UIApplication sendEvent:] + 73
5 UIKit 0x346f811b _UIApplicationHandleEvent + 6155
6 GraphicsServices 0x363ee5a3 _PurpleEventCallback + 591
When you add an observer to the notification centre you have to remove it when the object is being dealloced/destroyed. Otherwise Notification Centre would send the notification to the destroyed object resulting in crash.
1 - check if you properly handle the removing from notification centre. (typically you do this on dealloc method)
2 - If step 1 doesn't help, profile your application with instruments & zombies. it would point out which object is destroyed but still receiving messages.
Almost certainly an object registered with the notification centre to receive that notification and then failed to deregister before deallocation.
The easiest way to catch the problem would be to enable NSZombies — see e.g. this tutorial. If you run with zombies enabled then objects that should have been deallocated remain in memory but raise an exception if anyone attempts to call them. So you can figure out exactly what type of object the notification centre is attempting to call and therefore which object is probably making the mistake.
Given the name of the origin of the notification — _handleApplicationSuspend:eventInfo: — you might also want to have a quick check of anyone registering for UIApplicationWillResignActiveNotification, UIApplicationDidEnterBackgroundNotification and the others related to application suspension.
Might be an useful information that it appears to crash only on ios7, as my project ran perfectly on ios6.
Maybe userInfo is has nil value....
[[NSNotificationCenter defaultCenter] postNotificationName:SayLoggedInNotification object:wSelf userInfo:#{#"from": wSelf.from}];
# wSelf.form is nil

Why do i get exc bad access in cases when object is not nil?

I have an app that receives remote notifications. My view controller that is shown after push has a tableview. App crashes very randomly (1 in 20 tries) at line setting frame:
if (!myTableView) {
NSLog(#"self.myTableView is nil");
}
myTableView.frame=CGRectMake(0, 70, 320, 376);
This only happens when i open the app, then open some other apps and then receive the push notification. I guess it has something to do with memory. I use ARC (ios 5). The strange thing is that nslog is not displayed, so tableview is not nil.
Crash log:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x522d580c
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x352b1f7e objc_msgSend + 22
1 Foundation 0x37dc174c NSKVOPendingNotificationCreate + 216
2 Foundation 0x37dc1652 NSKeyValuePushPendingNotificationPerThread + 62
3 Foundation 0x37db3744 NSKeyValueWillChange + 408
4 Foundation 0x37d8a848 -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] + 176
5 Foundation 0x37e0ca14 _NSSetPointValueAndNotify + 76
6 UIKit 0x312af25a -[UIScrollView(Static) _adjustContentOffsetIfNecessary] + 1890
7 UIKit 0x312cca54 -[UIScrollView setFrame:] + 548
8 UIKit 0x312cc802 -[UITableView setFrame:] + 182
9 POViO 0x000913cc -[FeedVC viewWillAppear:] (FeedVC.m:303)
Dealloc is not called because it is not logged:
- (void)dealloc {
NSLog(#"dealloc");
}
You are having memory issues. Your tableView is reaching a retain count of zero; so although a pointer to the tableView still exists, the system has trashed the object at that actual address, hence the EXC_BAD_ACCESS.
It's possible that your UI that showed the tableView is hidden and therefore unloaded, but you've left some logic that assumes the table view still exists when it doesn't.
It's hard to debug what's going on without seeing more of the project. The best thing for you to do is have a careful look at the design of your application and UI flow. What would be causing the UI to be be released? How are you entering the code that assumes that part of the UI is still there?
N.B. Sending messages to a nil reference would not generate any errors; this is by language design.
I found the solution here:
Using ARC and UITableViewController is throwing Observation info was leaked, and may even become mistakenly attached to some other object
Seems pull to refresh (subview to tableview) was causing problems.
Do not change frame directly,do something like this.
CGRect frame = self. myTableView.frame;
frame.x =something;
frame.y=something;
myTableView.frame=frame;
and let me know.

iOS crash in CFStringGetLength in CoreFoundation

I'm getting a crash that, to me, seems as though it is a bug in the way that Apple is handling the goToDefaultLocation message of MKMapView. That message in turn calls [ALCityManager localeWithCode:], which calls [NSLocale componentsFromLocaleIdentifier:] which calls CFLocaleCreateComponentsFromLocaleIdentifier which calls CFStringGetLength and the crash occurs.
Can someone help to point me in the direction of either fixing the bug, if it is my code that is causing this, or, helping me find a workaround if, in fact, this is a bug in Apple's code (unlikely??).
Crash log below:
Incident Identifier: 84198BB6-45BD-493B-955F-75CCB5246DDD
CrashReporter Key: 7dbf53bf1f1a3635d7c3c49e726dedc609ed9f3a
Hardware Model: iPhone3,1
Process: MyApp [340]
Path: /var/mobile/Applications/DCE9A5A1-8E24-4D4F-A1ED-9855C6CA1742/MyApp.app/MyApp
Identifier: MyApp
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2011-03-25 10:36:06.382 -0700
OS Version: iPhone OS 4.3 (8F190)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 CoreFoundation 0x00009a66 CFStringGetLength + 6
1 CoreFoundation 0x0002f994 CFLocaleCreateComponentsFromLocaleIdentifier + 60
2 CoreFoundation 0x000483b8 +[NSLocale componentsFromLocaleIdentifier:] + 12
3 AppSupport 0x00016eee -[ALCityManager localeWithCode:] + 130
4 MapKit 0x00038488 -[MKMapView goToDefaultLocation] + 80
5 Foundation 0x000907c6 __NSFireTimer + 130
6 CoreFoundation 0x00075a40 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 8
7 CoreFoundation 0x00077ec4 __CFRunLoopDoTimer + 844
8 CoreFoundation 0x0007883e __CFRunLoopRun + 1082
9 CoreFoundation 0x00008ebc CFRunLoopRunSpecific + 224
10 CoreFoundation 0x00008dc4 CFRunLoopRunInMode + 52
11 GraphicsServices 0x00004418 GSEventRunModal + 108
12 GraphicsServices 0x000044c4 GSEventRun + 56
13 UIKit 0x0002ed62 -[UIApplication _run] + 398
14 UIKit 0x0002c800 UIApplicationMain + 664
15 MyApp 0x000023f0 main (main.m:34)
16 MyApp 0x00002370 start + 44
I got exactly the same crash reports, ONLY with iOS 4.3 / 4.3.1 AND iPhone 3GS/4 (armv7)
I think it is an Apple Bug, iOS4.3 has others ugly regressions concerning MapKit. (like the MKReverseGeocoder early releasing crash...)
An easy workaround would be to override -[MKMapView goToDefaultLocation] but at the risk of an Apple rejection since it is a private API... (Rejected for a bug workaround... I know... People are mean)
Another solution would be to analyze (reverse...) CFLocaleCreateComponentsFromLocaleIdentifier and componentsFromLocaleIdentifier: and [ALCityManager localeWithCode:] to understand how it can crash, being called with a nil locale identifier and maybe fix application locale programmatically, since it looks like the error coming from determining user's locale from device settings (or worse, from city/geolocation)... or at least WARN user that its locale settings might cause troubles...
Something I just can not(/want to) do, not being able to reproduce that bug.
Well your exception code is EXC_BAD_ACCESS. This is generally a memory-management error (i.e. some bit of code tried to access an object that had already been released/dealloc'ed).
It is possible but very unlikely that this is a bug in Apple/framework code. It's more likely that somewhere in your code you are either over-releasing something or hanging on to an auto-released object instance or otherwise accessing something that shouldn't be accessed.
Given that the crash happened in MapKit, I'd recommend looking at your map-related code for possible sources of this crash. Note that MapKit can be a bit tempermental; I've seen crashes in cases such as attempting to access the LocationManager's current-location when the user has location-services turned off. I'd expect such a case to fail (for instance, by returning a nil location), but not to crash the app.

iPhone Crash stack trace VS Crash report

Just spent some time... on a crash, without understanding it. That's a classic:
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000010
Which leads me to a memory issue, addressing the invalid adress 0x10
What bothers me is that I have crash report and stack trace, which differ:
The crash report, sent by user (symbolicated successfully, that happens) :
Thread 0 Crashed:
0 libobjc.A.dylib 0x000027d8 objc_msgSend + 16
1 UIKit 0x0005e9d2 -[UIViewAnimationState animationDidStop:finished:] + 54
2 QuartzCore 0x0002d8c2 run_animation_callbacks(double, void*) + 286
3 QuartzCore 0x0002d764 CA::timer_callback(__CFRunLoopTimer*, void*) + 116
4 CoreFoundation 0x000567f4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 8
5 CoreFoundation 0x000562a6 __CFRunLoopDoTimer + 854
6 CoreFoundation 0x0002779e __CFRunLoopRun + 1082
7 CoreFoundation 0x00027270 CFRunLoopRunSpecific + 224
8 CoreFoundation 0x00027178 CFRunLoopRunInMode + 52
9 GraphicsServices 0x000045ec GSEventRunModal + 108
10 GraphicsServices 0x00004698 GSEventRun + 56
11 UIKit 0x0000411c -[UIApplication _run] + 396
12 UIKit 0x00002128 UIApplicationMain + 664
13 MyApp 0x00003158 main (main.m:13)
14 MyApp 0x00003120 0x1000 + 8480
The crash stack trace (catched live by an Exception Handler)
0 MyApp 0x000d79c3 0x0 + 883139
1 MyApp 0x000d790b 0x0 + 882955
2 libSystem.B.dylib 0x302765d3 _sigtramp + 42
3 UIKit 0x31eab9d9 -[UIViewAnimationState animationDidStop:finished:] + 60
4 QuartzCore 0x33a178c9 _ZL23run_animation_callbacksdPv + 292
5 QuartzCore 0x33a1776b _ZN2CAL14timer_callbackEP16__CFRunLoopTimerPv + 122
6 CoreFoundation 0x3084e7fb __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
7 CoreFoundation 0x3084e2ad __CFRunLoopDoTimer + 860
8 CoreFoundation 0x3081f7a5 __CFRunLoopRun + 1088
9 CoreFoundation 0x3081f277 CFRunLoopRunSpecific + 230
10 CoreFoundation 0x3081f17f CFRunLoopRunInMode + 58
11 GraphicsServices 0x31e445f3 GSEventRunModal + 114
12 GraphicsServices 0x31e4469f GSEventRun + 62
13 UIKit 0x31e51123 -[UIApplication _run] + 402
14 UIKit 0x31e4f12f UIApplicationMain + 670
15 MyApp 0x0000315f 0x0 + 12639
16 MyApp 0x00003128 0x0 + 12584
Both differ, and the stack trace points to the crash in my code, but at addresses I can neither symbolicate nor identify. I think the crash report indicates that a message was sent to a released instance... Probably related to the use of :
+ (void)setAnimationDelegate:(id)delegate
+ (void)setAnimationDidStopSelector:(SEL)selector
So here (finally!) are my questions:
What explains the differences between logs? (libobjc.A vs libSystem.B ??)
Does the SIGBUS comes from my code or from UIKit?
How can I decipher the stack trace upper addresses (0x000d79??, which atos doesn't resolve)
Is that what I think, an issue related to an animation failing to end? similar to this > How to unset delegate on UIView setAnimationDelegate: call?
AFAIK, setAnimationDelegate is supposed to retain delegate... Someone to confirm?
EDIT: I can't use NSZombiesEnabled, this is a crash report from a published app, a crash that I didn't manage to reproduce on development environment. I just have these logs to diagnose.
Whenever I see objc_msgSend at the top, my trust of the remaining stack is low, as the error that gives this tends to do bad things to the stack.
GuardMalloc is good for this since the attempt to do anything with deallocated space will crash the app immediately in the debugger. The stack will be intact. (This makes the app very slow, but it is a very powerful tool.)
The two stacks are the same up to the UIViewAnimationState method call. The version that came from your exception handler is showing C++ mangled names instead of the regular names shown in the crash log.
(As I understand it) _sigtramp is the system's method of calling your signal handler and is short for Signal Trampoline. The stack entries beyond that are probably your signal-handler code.
Answering my own question, weeks laters, since I had no relevant answers, most are guesses, I wished I had more precise answers, but I guess my question was unclear :
Difference is coming from the origin of the log, a sighandler vs CrashReporter service, which are happening at different times, then the stack traces are slightly different.
SIGBUS comes from UIKit, but chances are big that's on a callback initiated from my code that ends on a released object. These kind of stack traces are a pain to debug when you can't reproduce the issue, since it basically tells you "I'm crashing somewhere because of an animation", which one, where... I still didn't figured precisely. Could be anywhere, and also could be an Apple iOS bug.
The first addresses in the stack are just a dead-end where any SIGBUS stack-trace ends when a released object is called. They differs across compilations (versions), but are the same on any device, That's why they can't be symbolicated. (I would love to have a technical explanation of this, instead of my guess)
& 5. I guess I solved this bug byt being more "agressive" on canceling animations in certain cases like on deallocation of some Views...
Hope that helps someone.
You should try NSZombie, to get information about what object you've released. This is a very useful tool when you get EXC_BAD_ACCESS.
To activate NSZombie do the following:
Get info of the executable.
Go to the arguments tab.
In the "Variables to be set in the environment:" section add:
Name: NSZombieEnabled
Value: YES
Then run your app as usual and when it crashes it should tell you which deallocated object received the message.
1. I'm not 100% sure but I think the discrepancy is due to how the application is being run. In the second log it looks like you're running the application via XCode in debug mode, a sigtramp signal has been sent to indicate a EXC_BAD_ACCESS error.
2. Your code - the error may come from the UIKit library but it's a result of a problem with your usage.
3. This is where NSZombieEnabled will make your life a lot easier! If you run your application with the NSZombieEnabled flag set XCode will keep 'zombie' objects in place of deallocated objects. When a zombie object is sent a message the process will trap the error and let you know exactly what object was sent the message.
If you're using XCode 4 enable NSZombieEnabled using the following instructions...
How do I set up NSZombieEnabled in Xcode 4?
For older versions follow these instructions...
http://www.cocoadev.com/index.pl?NSZombieEnabled
4. It does indeed appear that your animation delegate has been deallocated prior to the animation completing.

What do the memory addresses in iPhone crash logs signify?

I've been looking at crash logs generated by an iphone app today:
Thread 0 Crashed:
0 libobjc.A.dylib 0x3002d7da 0x3002b000 + 10202
1 UIKit 0x31ec4abc 0x31e4d000 + 490172
2 UIKit 0x31ebd214 0x31e4d000 + 459284
3 UIKit 0x31ebcfac 0x31e4d000 + 458668
Can anyone tell me what the hex addresses mean? (memory addresses, sure..)
I know how to symbolicate to produce:
0 libobjc.A.dylib 0x000027da objc_msgSend + 18
1 UIKit 0x00077abc -[UINavigationController _startDeferredTransitionIfNeeded] + 176
2 UIKit 0x00070214 -[UINavigationController pushViewController:transition:forceImmediate:] + 600
3 UIKit 0x0006ffac -[UINavigationController pushViewController:animated:] + 28
and debug the crash from there, but I'm curious; if you take
0x3002d7da 0x3002b000 + 10202
then: 0x3002d7da = 0x3002b000 + (decimal) 10202
What does this signify exactly?
I should add I'm not looking for info on how to symbolicate, thx!
EDIT: what is also strange to me is that if you compare pre and post symbolicated versions, then for code I wrote:
9 memleaktest 0x00002ffe 0x1000 + 8190
becomes
9 memleaktest 0x00002ffe -[memleaktestViewController buttonOne] (memleaktestViewController.m:24)
makes sense, but for framework code:
8 CoreFoundation 0x307fe52c 0x307f8000 + 25900
becomes
8 CoreFoundation 0x0000652c -[NSObject(NSObject) release] + 24
the address and offset has changed? Why would this be?
if you take
0x3002d7da 0x3002b000 + 10202
What does this signify exactly?
In this case, the "+" doesn't signify addition so much. What this line is telling you is:
The routine/library in question starts at address 0x3002b000
Your line-of-code in the stack trace happened 10202 bytes into it.
The sum of those two numbers = 0x3002d7da
(Put another way, as you did, 0x3002d7da = 0x3002b000 + 10202.)
The important thing about which you might care is the start address of the method being called.
But, really, you can ignore all of that, since it's not nearly as useful as the symbolicated version, which gives you source-file name & line-number.
Extending Olie's response on the "symbolicated version" of the app: The debugging information is stripped from the distribution version of the app to make it smaller and also to protect the developer's intellectual property (so you can't see class and method names).
In order to decrypt the log, you need to have the debugging symbols file associated with the specific build that created the crash log.
This file (.dSYM extension) will be present in the build folder where the binary of the iPhone app is also located. Please note that you need the .dSYM file for the specific compilation that was used to compile the app on the phone - the dSYM file is timestamped, so if you recompile the app, the dSYM file will change even if you don't change a line of code.
Once you have this file on your computer, drag the crash file into xcode (or view logs from attached devices in the Organiser), which will give you a stack trace of the methods called and the specific lines of code called which led to the crash.