1

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?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Tal Zion
  • 6,308
  • 3
  • 50
  • 73

2 Answers2

3

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.

Mattie
  • 2,868
  • 2
  • 25
  • 40
  • Having written that completely wrong code, I can say that there are much worse things than crashing. The version of this I tried to write could deadlock itself in some cases (of course none that happened before I shipped it) and drain the battery. A simple crash would have been far better. Please don't go down this road unless you are ready to do a great deal of system-level research and iterate on your solution for a few years, after studying those who have gone before you. (If you really do plan to build the next great crash reporter, then welcome and best of luck!) – Rob Napier Jan 07 '19 at 23:25
1

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.

Carl Lindberg
  • 2,902
  • 18
  • 22
  • 1
    Oh, you can do so much more harm… Deadlocks that drain the battery. Trashing user data. Oh, there's lots that can go wrong. – Rob Napier Jan 07 '19 at 23:27