Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EXC_BAD_ACCESS within main() with ARC but no hint on the error

I am running out of ideas. I receive an EXC_BAD_ACCESS on a project using ARC. According to the debugger it is within main(). NSZombieEnabled is set to YES but I do not see any callstack or Class/Type or anything. The same for the Inspector/Profile. All I get is "session timed out" some time after the app crashed.

And it is hard to locate within my code.

I am setting traces like

NSLog(@"CrashLog: <%@:%@:%d:%s>", NSStringFromClass([self class]),
NSStringFromSelector(_cmd), __LINE__, __FILE__);

all over my code on enty and exit of methods, but I did not yet identify any useful pattern. All I can see is that all my methods in question have been left already when the EXC_BAD_ACCESS is thrown.

Any idea on how to isolate the issue?

Tim suggested to use back trace (bt) in gdb. The result is:

#0  0x0be87580 in TI::Favonius::BeamSearch::choose_hit_test_node ()
#1  0x0be87b5f in TI::Favonius::BeamSearch::update_for_touch ()
#2  0x0be8ee32 in TI::Favonius::StrokeBuildManager::update_search_for_touch ()
#3  0x0be8f58f in TI::Favonius::StrokeBuildManager::key_down_or_drag_hit_test_for_UI ()
#4  0x0be6ba8b in TIInputManagerZephyr::simulate_touches_for_input_string ()
#5  0x0be7e5d9 in -[TIKeyboardInputManagerZephyr candidates] ()
#6  0x00678345 in -[UIKeyboardImpl generateAutocorrectionReplacements:] ()
#7  0x007dcaec in __71-[UITextInteractionAssistant scheduleReplacementsForRange:withOptions:]_block_invoke_0 ()
#8  0x007f6db2 in -[UITextSelectionView calculateAndShowReplacements:] ()
#9  0x00e255fd in __NSFireDelayedPerform ()
#10 0x01a03976 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#11 0x01a03417 in __CFRunLoopDoTimer ()
#12 0x019667e0 in __CFRunLoopRun ()
#13 0x01965dd4 in CFRunLoopRunSpecific ()
#14 0x01965ceb in CFRunLoopRunInMode ()
#15 0x01ccb879 in GSEventRunModal ()
#16 0x01ccb93e in GSEventRun ()
#17 0x0050d38b in UIApplicationMain ()
#18 0x000033e0 in main (argc=1, argv=0xbffff5fc) at /Users/Hermann/AppDev/fcApp/fcApp/main.m:16
like image 993
Hermann Klecker Avatar asked Feb 08 '12 20:02

Hermann Klecker


2 Answers

There are still ways to get EXC_BAD_ACCESS with ARC. Some that I ran into

  1. If you are doing something where you make an object and it asynchronously calls you back -- you have to make sure to keep a reference to it somewhere or ARC will release it. An example is the UIImagePicker -- you can't just make a local image picker variable and call it (and then release it when it calls you back) -- you have to make a property and hold onto it

  2. If you don't always use properties to hold onto it, you might run into trouble -- ARC is using the presence of strong and weak to know what to do -- if you use an ivar instead, you might fool ARC (not 100% sure of this). One easy way to make sure you don't do this is to use @synthesize var = _var instead of letting the property and ivar have the same name. This way, if you forget self.var = obj and just use var = obj it will complain.

  3. I ran into a bug in gestures and tabs -- the tab views didn't retain the gestures added by IB -- I documented it here

Crash when using gesture recognizers in StoryBoard

In these cases Zombies should help -- so it not helping means that you are probably not prematurely causing a release to happen. More likely you are munging memory -- I would check all casts and anywhere you are using built-in arrays or non-object pointers to make sure you aren't going out of bounds. Guard Malloc can help

https://developer.apple.com/library/ios/#documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html

like image 200
Lou Franco Avatar answered Nov 15 '22 06:11

Lou Franco


All right, finally I got it - nealy.

I do not yet know which detail was wrong. Finally I found out that the issue was related to an UITextView. Originally the text view was not intended to be editable. But I wanted to receive touch-events. so I follwed one of the advises given hiere: (iPhone) How to handle touches on a UITextView? I assigned 'self' (a UIViewController subclass) as the UITextView's delegate and barely implemeted the protocol in this way:

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
    [self userShow:nil]; //Within this method a subsequent UIViewController subclass/object is created and pushed.
    return FALSE;
}

- (BOOL)textViewShouldEndEditing:(UITextView *)textView{
    return TRUE;
}

- (void)textViewDidBeginEditing:(UITextView *)textView{
    return;
}

- (void)textViewDidEndEditing:(UITextView *)textView{
    return;
}


- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
    return TRUE;
}

- (void)textViewDidChange:(UITextView *)textView{
    return;
}

- (void)textViewDidChangeSelection:(UITextView *)textView{
    return;
}

The intention was to actually avoid editing but receive the event when a user touches the area of the UITextView and invoke some action. In this case some subsequent view controller was created and pushed to the navigation stack. It worked fine but some time later, in some cases minutes (!) the app crashed. Thanks to Lou's answer and his blog I was able to get the EXC_BAD_ACCESS much closer to the call of textViewShouldBeginEditing. Similar to earler desparate attemts of getting around the EXC_BAD_ACCESS I commented out the UITextView and invoked the view controller to be called using some other UIButton item. (Just a quick temp workaround) Luckyly this did the trick. The app did not crash anymore. Now I will go for some more sophisticated implementation that will bring the same user experience but call the other view controller in a different but save way.

I provide this answer just in case somebody else runs into the same issue. If you have an explanation at hand about which detail exactly caused the issue, then your hit is highly appreciated.

like image 24
Hermann Klecker Avatar answered Nov 15 '22 06:11

Hermann Klecker