Break on `unrecognized selector sent to instance` during debuging session - xcode

While debugging a view hiearchy with expression -o -- (NSString *)[[UIWindow keyWindow] recursiveDescription] I've received a -[UILabel length]: unrecognized selector sent to instance 0xd4ebe50. I would like to use LLDB to debug the problem and get a stack trace if the debugger gets an unrecognized selector.
I've tried
setting an exception breakpoint in Xcode
setting a breakpoint w/ breakpoint set --selector length and
setting a breakpoint w/ breakpoint set --selector -[UILabel length]
Setting a breakpoint manually leads to the warning WARNING: Unable to resolve breakpoint to any actual locations. The breakpoints are not triggered during debugging.
Is it possible to stop on unrecognized selector and get a stack trace?

In xCode you can set breakpoints to all Objective-C unhanded exceptions. To do that, in the Breakpoint Navigator, press the + symbol in the bottom-left corner of the navigator, and select "Add Exception Breakpoint":
You will see an "All exceptions" entry. Right click that, select Edit Breakpoint and configure it as follows:
Then, when your app crashes, the execution will break in the conflict code, showing the stack trace and all the information you need.
Hope it helps!

Underlying the Xcode Objective-C exception breakpoint in #lucaslt89's answer is an lldb breakpoint which is simply:
breakpoint set --name objc_exception_throw
For an unrecognized selector error you can also break on -[NSObject(NSObject) doesNotRecognizeSelector:].

breakpoint set --selector didn't work correctly in Xcode 4.6 without a dSYM for the relevant library (UIKit in this case).
I would expect breakpoint set -n "-[UILabel length]" to work though. Or you can add a Symbolic breakpoint in Xcode. Debug > Breakpoints > Create Symbolic Breakpoint and you should be able to enter -[UILabel length].
Keep in mind that the shortest unique command is always valid in lldb, so br s -S length would be another way to write breakpoint set --selector length.
A similar question is over in unrecognized selector sent to instance where one recommendation is to po 0xd4ebe50.

Is it possible to stop on unrecognized selector and get a stack trace?
To stop lldb from rewinding the app state call expression with --unwind-on-error false (short: -u false). lldb will not clean up the state, if this option was used.
However, this didn't helped me to debug where in the view hierarchy the label was located. lldb told me from the very beginning, that the label could be found at address 0xd4ebe50. The output of po [0xd4ebe50 text] gave me a clue where to investigate. I've added a green background to the label for further assistance. The culprit was a label named description which caused the problem in regards to -recursiveDescription.

Related

failed to set breakpoint site at 0x9dd200 for breakpoint 197.1: error sending the breakpoint request

I can not make a breakpoint in my xcode.
It print "warning: failed to set breakpoint site at 0x85d5f0 for breakpoint 279.2: error sending the breakpoint request
" all the time
You've most likely deleted the file or the file / folder structure changed such that the breakpoint is now invalid. Switch to the Breakpoint Navigator in Xcode and find (and delete) all the files marked in red. You can even enter "279.2" in the search field below the panel to find out the faulty breakpoint.
If you're unable to create breakpoints still, make sure the file you're adding break point to has been added to the target you're debugging.
In my case I forgot to set initial view controller in storyboard.

How to find the location of error in Xcode

How can I change the preferences in Xcode so that it highlights the exact location of an error like other programming environments instead of simply returning SIGABRT? Or is this not possible?
Xcode should already stop and show where execution is when a signal like SIGABRT occurs. (It does for me, without any special configuration).
a NSInvalidArgumentException occurs Xcode only highlights main.m
It's not signals you need to catch for that, it's exceptions. Go to the breakpoint navigator and add an exception breakpoint.

Can get location of exception with Xcode or explanation... how can I get both?

If I don't set a breakpoint on exceptions in Xcode 4.2, I get very good explanations, like this one:
exception -[NSLayoutManager
_fillGlyphHoleForCharacterRange:startGlyphIndex:desiredNumberOfCharacters:] *** attempted
glyph generation while textStorage is editing. It is not valid to cause the
layoutManager to do glyph generation while the textStorage is editing
(ie the textStorage has been sent a beginEditing message without a matching endEditing.)
If I do set a breakpoint, I get the location of the problem, which is also good. But then I don't get the explanation. Nothing at all is written to the console, even if I continue.
How can I get both? Presumably, since Xcode stopped on the exception, the exception object is somewhere in the debugger when I can get to it.
Enable Zombie Objects for get location of exception:
Go to menu Product -> Scheme -> Edit Scheme... -> tab Diagnostics -> ON checkbox Enable Zombie Objects

Xcode 4 doesn't show the exception message

I had a xib file with an old outlet connected. That would crash and set a breakpoint on the line pushing the view controller with :
Catchpoint 2 (throw)Pending breakpoint 1 - "objc_exception_throw" resolved
Not very helpful, I remember in XCode 3 I had something like "an outlet is not connected"
How do I get that back ?
edit : if I check "automatically continue after evaluating actions", I get this message :
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<OrderController 0x7942760> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key table.'
*** First throw call stack:
(0x16e1052 0x2182d0a 0x16e0f11 0x4cb032 0x43cf7b 0x43ceeb 0x457d60 0x99991a 0x16e2e1a 0x164c821 0x99846e 0x83fe2c 0x8403a9 0x8405cb 0x840941 0x85247d 0x85266f 0x85293b 0x8533df 0x853986 0xcf67dbd 0x8535a4 0x3a3da 0x841fbf 0x8422d4 0x8425d7 0x842785 0x85c0a5 0x842730 0x78b5ea 0x16b59ce 0x164c670 0x16184f6 0x1617db4 0x1617ccb 0x18f7879 0x18f793e 0x77aa9b 0x276d 0x1fd5)
terminate called throwing an exceptionCurrent language: auto; currently objective-c
(gdb)
which is better than nother, but the breakpoint stops on main.m ! Here is the current setup of my breakpoint
Mystery solved. At least for me, hitting 'continue' a couple of times allowed the error to be printed to the console.
The issue (in this case) was having a couple of other custom breakpoints set (objc_exception_throw, -[NSException raise]).
Enabling "automatically continue after evaluating" for BOTH allowed the process to be killed without manual intervention, somewhere around which time the detailed error message was printed to the console.
Hope this helps.
If you have multiple projects, make sure that the breakpoint is active for the correct project. I recommend using a Xcode 4 workspace in this case and assign the global exceptions breakpoint to the workspace. You can do that by right-clicking the breakpoint in the Breakpoints Navigator pane and select "Move Breakpoint to…"

Help with Exception Breakpoint in XCode 4

I've set up an Exception Breakpoint in XCode 4. Will it break for exceptions that originate within the Cocoa Touch framework AND are handled by the framework? I.E. Will the debugger stop for all exceptions, even if they are a natural part of the framework and handled by it internally?
My debugger keeps halting for a seemingly harmless exception from deep down in the framework and I need to know if I can safely ignore it.
If you're like me, there are times you want to ignore particular exceptions (like Apple's intermittently buggy CMMThrowExceptionOnError, which Apple neglects to provide any feedback to my bug reports for months)
So, my not-very-efficient solution is to add the following breakpoint instead of 'Add C++ Exception Breakpoint...'
from gdb command line, enter
break __cxa_throw
Then, in the XCode breakpoints editor, add the following 'Debugger Command' to this breakpoint. By substituting the offending address of $eip, you can exclude individual
exceptions from your breakpoint.
silent
# go up one stack frame silently
up-silently
# in my particular app, address of CMMThrowExceptionOnError is 0x9704d22e
if ( $eip == 0x9704d22e )
# echo gdb ignore exception\n
#print $eip
cont
end
If you can devise a better solution which doesn't incur the overhead of a debugger script, please let me know.
The exception breakpoint is just that: a breakpoint for exceptions. This includes those within the framework. It doesn't matter whose exception it is - if it's raised, it should break.
Just a short note on LLDB used by defat in Xcode 4.3
Commands have a different syntax.
set $eip = xxxx
is now
reg write tip 0x006373ec
a full map of commands is available at http://lldb.llvm.org/lldb-gdb.html

Resources