I will probably write a longer article on exception handling in XCode, for now just a quickie: how to use XCode 4 exception breakpoints, use the breakpoint customization features and get useful information for debugging. Usually when the app is crashing, a lot of cryptical mumbo-jumbo is displayed in the console. You have to dig the entire dump to understand what is happening. Worse, most frequently the SIGABRT is signalled by main thread in application loop:
Which leaves you with very few clues on what is actually happening. Of course, digging into the stack dump on console will probably reveal the culprit (in this case a message sent to a non-existent selector):
[debugger]2013-01-29 16:55:49.167 NSOutlineView_Simple_Two_Dictionaries[1164:303] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[NSOutlineView setIndentationPerLevel::]: unrecognized selector sent to instance 0x102216b50’
*** First throw call stack:
0 CoreFoundation 0x00007fff8668d0a6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff890ca3f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff867236ea -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
3 CoreFoundation 0x00007fff8667b5ce ___forwarding___ + 414
4 CoreFoundation 0x00007fff8667b3b8 _CF_forwarding_prep_0 + 232
5 NSOutlineView_Simple_Two_Dictionaries 0x0000000100002663 -[OutlineViewController outlineView:dataCellForTableColumn:item:] + 131
libc++abi.dylib: terminate called throwing an exception
Would be nicer to debug the app and make it break and indicate the position that raised the exception. Comes in light XCode 4 exception breakpoints.
Press Cmd + 6 to access the Breakpoint navigator, then click on the small plus sign in the bottom left corner:
This will bring up two options. Exception and Symbolic Breakpoint. I will cover creation and usage of symbolic breakpoints in another post because there is a much more elaborated discussion.
For now, I chose Add Exception Breakpoint. A pop-up will appear with some options to customize the breakpoint. For now I
will leave all values at default and click on “Done” button. This will add an exception breakpoint for any exception thrown by the application and will force execution to break when the exception is thrown (there are two options, “on throw” and “on catch”). When program is ran again with debugging on, will still crash, but instead of getting a full stack dump on the console and a SIGABRT indication on main, the app stops and indicates the origin of the crash:
I am using this for all my projects. First thing, after project setup, I add an exception breakpoint. That is very handy and saves a lot of debugging time. Hope you will find it useful.