Many OS X crash reports have this section like in a quote below
Exception Type: EXC_CRASH (SIGABRT) Exception Codes:
0x0000000000000000, 0x0000000000000000
Application Specific Information: objc[1769]: garbage collection is
OFF
Terminating app due to uncaught exception 'InvalidX', reason: 'X can't be 0'
First throw call stack:
In my application there's custom crashes handling. All I can is to handle signals, nothing else. Where can I retrieve such useful information?
I found that you can set the message to show in built-in crash reports
static const char *__crashreporter_info__ = 0;
asm(".desc __crashreporter_info__, 0x10");
But I want not to set, but retrieve that information in my custom signal and exception handler.
The technique changes every few releases of the OS. In general, the crash reporter enumerates the images in the process using the dyld debugger API, and extracts any information from crash buffers in each one. Currently, IIRC, there is a specially named Mach-O section in the data segment which points to (or contains) a static variable containing the data.
If you are looking to generate a crash report, the following shows how to catch the Mach message as a result of the exception and then generate a crash report.
How does OS X generate a crash report?
Related
I have a very peculiar issue.
Recently I added 64bit support to my iOS project (arm64), ever since doing that I started receiving uncaught exceptions for segments of my code inside #try...#catch (I'm using Crashlytics for crash reporting). I managed to reproduce the problem with the following lines of code anywhere in my app (I wrote them inside init of one of my view controllers):
#try {
NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
NSString *s;
m[s] = #"poop";
} #catch (NSException *e) {
NSLog(#"POOP");
}
The exception gets caught by the UncaughtExceptionHandler instead of the #catch clause. I'm confused as to what can cause this. The output in the console:
2015-02-22 19:19:53.525 [391:30650] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil'
*** First throw call stack:
(0x18823a59c 0x1989400e4 0x1881251f8 0x10011e2f4 0x10011e068 0x10010e480 0x10010db78 0x10010d944 0x1000a8050 0x100075d88 0x100075160 0x100142044 0x100141f6c 0x18c9ecaa0 0x18caa1fb4 0x18caa1eb0 0x18caa134c 0x18caa0ff8 0x18caa0d18 0x18caa0c98 0x18c9e9648 0x18c341994 0x18c33c564 0x18c33c408 0x18c33bc08 0x18c33b98c 0x18cc76dbc 0x18cc77c68 0x18cc75dec 0x1904b162c 0x1881f2a28 0x1881f1b30 0x1881efd30 0x18811d0a4 0x18ca573c8 0x18ca523c0 0x1000747d8 0x198faea08)
libc++abi.dylib: terminating with uncaught exception of type NSException
I tried removing the custom exception handler that I have and disabling Crashlytics, still no success.
As soon as I remove arm64 from ARCHS and VALID_ARCHS the code works and the exception is caught as expected.
Any information will be appreciated!
Small update - our XCTests also started not to catch exceptions, up until now the behaviour only happened on physical 64bit phones.
After a long session of git-bisecting the culprit was the following linker flag
-no_compact_unwind
I Used BlocksKit v2.2.0 which still had that flag even though it stopped using libffi (latest version of BlocksKit removed that unneeded flag). As soon as I removed that linker flag 64bit #try...#catch blocks started to work again.
I still don't have complete understanding of why this behaviour happens but I'm going to dig a bit more and update this thread if I find anything interesting.
phew
On iOS and Objective-C Exceptions are only to be used for un-recoverable programming errors, not for program execution control.
In particular they do not handle catches accross stack frames inthe APIs.
So I keep getting this crash and break in my code, but I can't figure out exactly where it's coming from. Xcode doesn't break on the line that is relevant to this, and I looked through all of the thread stacks and none of them show the break. Here is what I am getting:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '***
Collection <CALayerArray: 0x17746b10> was mutated while being enumerated.'
My question is, how so I find out where this array is? Is there some way to look it up in the Xcode console by address to point me to what exactly is happening here? I can't find where I would be mutating some array just by eyeballing my code.
Add exception breakpoint and check the location for crash.
1) Go to the breakpoint navigator.
2) At the bottom left corner click on the ADD
3) Now select "Add Exception Bearkpoint" in that.
4) Make sure "Exception Breakpoint" is enabled.
5) Right click on breakpoint and Change the exception type to Objective-C.
Now run you app and debug the crash area.
SUMMARY
When I set an exception breakpoint, I don't get the exception message. How do I get the exception message? I already know how to get the stack trace, but that doesn't include the exception message.
DETAILS
In the past I developed iOS Apps with Xcode and when there was a problem, I'd get an error/exception. The exception would often have a message like "can't dereference null" or whatever.
Now, using Xcode 4.6.x for the past several weeks I've never gotten an exception message. I'll often get a SIGABRT. I put in the break on exception breakpoint and it will break there, but it's off in some assembly within the iOS SDK and I never get a message.
In fact, I can't remember the last time I saw anything show up in the debugger console.
Did exception info dissappear with the migration to LLVM?
It's very frustrating to have my app just crash in the SDK without knowing why. I check the last function to make sure things are set up correctly (objects allocated, etc) and they are which means I'm left with no clues.
Is it possibly a build setting held over from the past is somehow turning off exception messages?
Please reopen question. It now has an answer!
In the comments an excellent answer has been given. This should be promoted to full answer, and so I can mark the question answered and others who have this common issue can find it. In order for that to happen, the question needs to be reopened! (I'll delete this plea after that happens.)
I will update Jeff's answer here:
To have both the line causing the exception highlighted (and not UIApplicationMain() in main.m) AND to see the reason for the exception (e.g., "error: A fetch request must have an entity."), do this:
In the Breakpoint navigator:
Add (+), Add Exception Breakpoint
Select the new breakpoint, Control-Click, Edit Breakpoint
Add Action
Enter: po $arg1
The relevant part of the stack trace will be in the nagivator area.
This seems to still work in Xcode 9
Here is my addition for use with Xcode 6 and below.
Enter: po (NSException*) $eax
In Xcode 6 you must explicitly provide the object type because it is no longer inferred.
For Xcode 7-9 (based off Jeff's answer):
In the Breakpoint navigator:
Add (+), Add Exception Breakpoint
Select the new breakpoint, Control-Click, Edit Breakpoint
Add Action
Enter: po $arg1
To have both the line causing the exception highlighted (and not UIApplicationMain() in main.m) AND to see the reason for the exception (e.g., "error: A fetch request must have an entity."), do this:
In the Breakpoint navigator:
Add (+), Add Exception Breakpoint
Select the new breakpoint, Contorl-Click, Edit Breakpoint
Add Action
Enter: po $eax
The relevant part of the stack trace will be in the nagivator area.
Yes xcode is not so friendly for debugging. I like this article which helps me to understand crash logs a bit clearly))
Demystifying iOS Application Crash Logs
Also do this if you see error "message sent to deallocated instance"
'Products -> Edit Scheme -> Enable Zombie Objects'
this will enable zombie objects and when you do profile to your project choose
"zombie", cause error and you will be able to see which objects was deallocated e.g NSArray *myArray
The information I get from po $eax or po (NSException *)$eax seems to be different from what Xcode would print if no exception breakpoints are set. So I do the following,
Add an exception breakpoint
Exception occurs, breakpoint was hit -> I know the location
Temporarily disable breakpoints (second button on the left in Debug area)
Continue program execution (third button on the left in Debug area)
Details are printed -> I know the cause
Obviously not very elegant and flexible, but at least I two big questions are answered (where and why).
You can use bt or thread backtrace command to print error trace
Show the stack backtrace for the current thread.
The same stack trace you can find in crash reports
Information about current thread use currentThread
//Objective-C
po [NSThread currentThread]
//Swift
po Thread.currentThread
*Sometimes you can use fr v(or just v from XCode 10.2) when po is not working
In Apple crash reports, there are two lines providing Exception Type and Exception Codes for the crash report. Does anybody know what all these codes actually mean?
There are some self-explaining ones ones, like KERN_INVALID_ADDRESS:
For example, this one is a NULL Pointer dereference:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
If you made an error with pointer arithmetic, you'll end up with something very similar:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00007fff50399000
But there are lots of these exception codes! For example, here's one I recently encountered and I have no clue what it means (the address points to a big memory-mapped file):
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: 0x000000000000000a, 0x0000000137676004
All I found about crash reports was this technote, but no detailed reference how to interpret exception codes.
A list of exception codes can be found in the xnu source. 0x000000000000000a is KERN_MEM0RY_ERROR:
#define KERN_MEMORY_ERROR 10
/* During a page fault, the memory object indicated
* that the data could not be returned. This failure
* may be temporary; future attempts to access this
* same data may succeed, as defined by the memory
* object.
*/
Using Xcode 4.3.2. I looked at many different similar issues including this one
no-call-stack-on-exception-in-xcode-4
but cannot get the debugger (gdb or lldb) to give me a good stack trace that shows the location of the exception AND to also prints what the exception is
Setting either a symbolic exception on objc_exception_throw or an "All Exceptions" exception breakpoint, lldb would not give me a good stack trace but would show the following:
thread #1: tid = 0x1c03, 0x34455238 libobjc.A.dylibobjc_exception_throw, stop reason = breakpoint 1.1
frame #0: 0x34455238 libobjc.A.dylibobjc_exception_throw
frame #1: 0x323ff788 CoreFoundation`+[NSException raise:format:arguments:] + 100
That is the whole thing, either through bt or at full magnification in the graphical breakpoint/debugger view.
If I hit continue a few time at this point it will eventually tell me the exception/assertion, for example
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '_endUndoGroupRemovingIfEmpty:: NSUndoManager 0x2b7610 is in invalid state, endUndoGrouping called with no matching begin
But I have no idea where it is at.
gdb, using the same breakpoint, WILL stop and show me where it is at, but does not print the exception text. If I hit continue a few times it does but I have lost my context of the back trace.
I would like to know how to print the exception text so I know WHY it stopped, without having to do a few continues and losing my place. I would also like to get it to stop in lldb at the point of the exception like it does in gdb.
Please try updating to Xcode 4.5. You're seeing an armv7 unwinder problem where lldb doesn't know how to unwind your stack completely. The Objective-C runtime has some functions that are difficult to unwind out of (hand-written assembly) but I just did a quick test on an iOS device with Xcode 4.5 and lldb behaved correctly when I had Xcode set an Exception Breakpoint on throw.