Tal Zion
Tal Zion

Reputation: 6526

How to set a new handler/responder for EXC_BAD_ACCESS crashes

I am looking for ways to override the responder/handler for EXC_BAD_ACCESS. This is how I've set the handler for signal crashes or NSException which works fine:

NSSetUncaughtExceptionHandler(newExceptionHandler)
signal(SIGABRT, newSignalHandler)
signal(SIGILL, newSignalHandler)

I tried this but this is not getting called:

signal(EXC_BAD_ACCESS, newSignalHandler)

Any idea?

Upvotes: 1

Views: 605

Answers (2)

Mattie
Mattie

Reputation: 3028

As Carl mentions, intercepting crashing events on iOS (and macOS) is fraught with peril for variety of reasons. I was the Crashlytics SDK maintainer for a while, and I would recommend strongly against doing it.

But, it definitely is possible.

One thing that seems to trip people up a lot is the relationship between signals, exceptions (ObjC or C++), and mach exceptions. These are all very different things.

On iOS (and tvOS, macOS) the events that terminate a process are mach exceptions. These are the low-level events that you can, in fact, intercept. When you see that EXC_ prefix, you know you're looking at a mach exception. I believe these are all defined in mach/exception.h.

Now, iOS has an interesting implementation where if there are no mach exception handlers, the OS translates the event into a unix signal. The signal function can be used to intercept these. Since EXC_BAD_ACCESS is not a unix signal, it is not a valid argument to the signal function. But, you can add handlers to those signals listed, and they will give you roughly the same information.

Mach exceptions are a significantly more powerful and safer mechanism for intercepting these kinds of events. Unfortunately, they also require a dramatically more complex handling system. Signals have all kinds of problems, but they are a lot easier to use.

I would be interested to know what you're trying to do, in case perhaps there's a better way of achieving what you are after.

Again, I'd avoid going down this road. It just isn't worth your time. It is challenging to get things working at all, and when you do, you'll be lulled into a false sense of security. You might even think things are working right, because the times your code goes completely wrong, you'll never know and you'll just get weird reports from users of random hangs from time to time.

Upvotes: 3

Carl Lindberg
Carl Lindberg

Reputation: 2972

If you are not using an existing crash reporter (they are very hard to write on your own, when dealing with corrupted memory and the like), you might look to their sources to see which signals they are handling. For example, PLCrashReporter's PLCrashReporter.m hooks onto SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, and SIGTRAP, which seems to be the usual list for crash handlers. EXC_BAD_ACCESS should turn into either SIGBUS or SIGSEGV. Writing re-entrant code correctly in signal handlers is extremely difficult (can't use any ObjC or really most C APIs in there), so be careful -- though I guess if you are already crashing, can't do much more harm. But the more careful you are, the more exceptions you will handle without crashing further.

Upvotes: 1

Related Questions