Alternative to NSSetUncaughtExceptionHandler on iPhone - iphone

I'm trying to make a general error handler for an iPhone app that brings the user to a recovery screen whenever any general error is thrown in the application without putting a try/catch block around every single method in the application.
Using NSSetUncaughtExceptionHandler doesn't work because the application terminates after the handler is run.
Is there any way to change this behavior, or use any other handler that will catch exceptions in general and not cause the application to exit afterward?
And please, no non-answers about whether it's a good or bad idea.

The original poster has probably solved his problem by now. However, for anyone who comes across this in the future...
Matt Gallagher wrote an excellent post on catching unhandled exceptions and signals a few months after this question was posted. I find it to be much more informative than the answer referenced above by Scott.
In particular, Matt's post describes how to attempt a recovery (if appropriate) that allows your app to keep running, and even displays a UIAlertView with error information if you want (hint: it involves creating a new run loop).

This was answered here. You can read more about the responder chain and catching the exceptions here. The write up from 1 is really good and explains how to deal with what you are doing.

Related

Iphone random crash issue

Recently my iphone project comes to the end, but suffer some random crash during app running, and the call stack is always located in COCOA library, tough issue, don't know how to deal with it, for some cases I even suspect that is it apple's defect?
My questions.
For those random crash issue with few reproduce rate, how do you guys handle it? Any method to help to increase reproducible rate?
How to fix these crashes located in COCOA library? How to find more clues?
Any idea or discussion will be appreciated, thanks in advance.
If the app crashes in the COCOA code it does not mean that COCOA code is wrong - much more likely you fed some invalid data to it (for example nil where it does not supposed to be). If it's happening randomly there might be some multithreading concurrency behind or some of your objects become (auto)released too early, etc. You have to carefully analyze your code which operates with the COCOA classes where your crash happens, or try memory management debugging as suggested by other answerers.
Generally, I don't start thinking that is COCOA the problem. It happens, but most cases the fault is ours.
When this kind of crashes happens the first thing to do is to run the static Analyzer, sometimes it's just a retain/release problem.
If you're using ARC, skip this part and start creating an Exception Breakpoint (search 'To add an exception breakpoint...' in linked guide). The exception breakpoint helps to have a more detailed crash log when an exception is thrown.
The third step is using Instruments, looking for waster memory, leaks and any other form of memory drain. How to use Instruments is deeply explained in a couple of WWDC videos.
Enable NSZombie flag.
project(On Top LeftCorner of xcode)>Diagnostics>enable zombie objects
It will lte u know where ur code is crashing ..find it fix it

Get previous run, crash logs on iPhone

I trying to write a a crash report feature that when you launch the app after a crash, it will offer to send the crash report to the server. I can't find how to get the crash log within the app. I saw there is a framework that doing so (PLCrashReporter), however this framework is large and I don't need most of it's features.
Does anyone knows how to simply access the log?
Thanks,
Guy.
I guess I don't have the karma to add a comment to Nimrod Gat's answer, so I have to provide my follow-up here. I'll try to make it worthy of a standalone answer.
It's very, very difficult to write a safe, correct, and reliable crash reporter, especially one that runs directly in-process. The code referenced in Nimrod Gat's answer is not correct and honestly, that blog post should be retracted. Signal handlers must only run async-safe code, and that code isn't async-safe:
http://www.cocoadev.com/index.pl?SignalSafety
Crash handling is even more complicated than normal signal handling, because that you can't expect the process to continue to run successfully after your signal handler returns.
It's tempting to think you can just hack together a simpler solution, and it will work some of the time, but there's a good reason people like Google's engineers have thousands of LoC dedicated to reliable crash reporting:
http://code.google.com/p/google-breakpad/
On iOS, you should just use PLCrashReporter. On other platforms (such as Mac OS X) you should use Google Breakpad. There's no point in re-inventing this wheel unless you're going to do it not only correctly, but better than what already exists.
I had this similar issue and the PLCrashReported seemed too complicated for what I wanted to do.
Note that you can't access the crash report generated by Apple, the PLCrashReport generates it's own reports and store them in the user's cache folder.
Eventually, I used the following example:
http://cocoawithlove.com/2010/05/handling-unhandled-exceptions-and.html
it's very simple and easy to use, just register exception and signal handlers using:
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
and get the stack trace using the backtrace method in UncaughtExceptionHandler class.
Maybe a better solution will be to use a fully specialized end-2-end solution/service? Such as http://apphance.com. It is currently in closed beta testing phase, but you can ask for participation and we'll get back to you pretty quickly. The only thing you need to do is to register for an API key and embed a small framework library into your app (or .jar file in android). Then you have remote access not only to crashlogs but also to a debug logs generated by the application - which makes it much more useful. It is for now targeted to be used during testing, but there will soon be a lite version that you will be able to embed into app-store-released application.
Inside the framework we are doing all the magic of plugging-into the apple's framework and getting the crashlog information, decoding stack traces, even handling out-of-memory cases. All the comments by #nupark hold very much true: We spend countless hours on making it works seamlessly - thread-safeness, making sure that we can do the job of saving everything within the time required by Apple's framework before your app get finally killed, getting stack trace from out-of-memory case (that one was really difficult). The same for android - we've done some clever tricks there to make sure it's really working fine.
Disclaimer: I am CTO of Polidea, company which is behind apphance and co-creator of the solution.
There are a bunch of (SAAS) E2E solutions that you may be very happy to know.
Very very simple to integrate into your application
Have Fun...
crashlytics (Free and my preferred)
hockeyapp
bugSense
Crittercism
In our days you may use the built-in crash reports (iOS & Android)
iOS (Itunes connect) - Viewing Crash Reports
Understanding Crash Reports
on iPhone OS
Reading Android Market Crash Reports

iOS - Global exception handler

Is there anyway to implement a global exception handler for iPhone apps such that exceptions, instead of silently crashing the app, could allow for some sort of message?
I can understand if it's not do-able since the program may be in an inconsistent state, but it'd be nice to at least tell users "Sorry - something went wrong!"
Thanks!
Check this question for the answer. It seems to indicate that you'll be getting junky stack traces, but you definitely can set a global exception handler. Good luck!

handling a fatal error in iphone app

how to handle error in an iphone app ?
log and exit ? show an alert dialog and exit ?
for exemple, if an image is missing from the bundle..even though it should not ...
You are never supposed to exit the app programmatically. Advise the user there was a problem, offer to try it again, etc. But don't kill the app. This is explicit in the Apple HIG.
Let the user decide your app needs exiting. Don't do it for them.
Ideally, don't get yourself in this situation. : ) Easier said than done I know.
#Genericrich has it pretty spot on:
Advise the user there was a problem, offer to try it again, etc. But don't kill the app. This is explicit in the Apple HIG.
The only advice I would add is to expect the unexpected. Just make sure your app is ready for those little blowups. This might be things like: default information to fill in the blanks, adequate alerts to let users know what's happening/retry, saving state before attempting failure prone destructive actions, and any other defensive programming habits you can think of.
As an added note if you are wanting to test network errors you may want to check out Craig Hockenberry's excellent post Slow ride, make it easy on the subject.
Alert box and exit should be fine. Short and sweet with just enough communication with the user to let them know why your software is about to not work.

iphone error dialog?

I wonder if is possible display a dialgo when a unexpected error happend in the iPhone (and not quit blindy the app!) and have time to log or send by email the crash...
Yes. For starts implement NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler) and then use something like Crash Reporter. Good stuff.
I don't know if you can show a dialog, but you can probably do some logging by specifying a top-level exception handler using the function NSSetUncaughtExceptionHandler
I remember there being a method you could override in your application delegate class that would be called in the event of an unhandled exception. A few days ago someone wrote a blog post where they shipped off the exception information to a web service from that method.
I apologize that I can neither find the name of the method in the UIApplicationDelegate protocol or the blog post I saw the other day. Apple's online documentation seems to be un-searchable at the moment (grrr!) and I cannot remember where I saw that blog post - if I find it, I'll edit this post to include a link to it.
But it may be possible to have some sort of recovery, or at least the ability to store off error information to disk so it can be sent later.