14

I'm trying to build my own signal and uncaught exception handler for iOS. To do this i use these two functions :

NSSetUncaughtExceptionHandler(/*handler*/); 

and

signal(/*signal const*/, /*signal handler*/);

My problem is that i can't make it work with EXC_BAD_ACCESS signal. Is there some signal constant (like SIGABRT, SIGBUS) to catch the EXC_BAD_ACCESS? If no, how can i handle it? Some crash analytics tools (lika PLCrashReporter, Crashlytics etc.) can trace it...

animal_chin
  • 6,610
  • 9
  • 37
  • 41
  • 1
    See this post: http://stackoverflow.com/questions/1128539/nssetuncaughtexceptionhandler-not-catch-all-errors-on-iphone – Lefteris Apr 25 '12 at 12:33
  • well, ive already included SIGSEGV but it still doesnt catch EXC_BAD ACCESS :/ hmmmm... but thanks for comment! :) – animal_chin Apr 25 '12 at 12:37

1 Answers1

9

EXC_BAD_ACCESS doesn't generate an exception so you first function doesn't work with the case. It generates a signal SIGSEGV or SIGBUS.

Please refer to Handling unhandled exceptions and signals by Cocoa with Love.

Update

I just checked the source code of LLDB. It might be TARGET_EXC_BAD_ACCESS = 0x91.

In RNBRemote.h:

/* We translate the /usr/include/mach/exception_types.h exception types
   (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses
   in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS).  These hard
   coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb
   values in its include/gdb/signals.h.  */

#define TARGET_EXC_BAD_ACCESS      0x91
#define TARGET_EXC_BAD_INSTRUCTION 0x92
#define TARGET_EXC_ARITHMETIC      0x93
#define TARGET_EXC_EMULATION       0x94
#define TARGET_EXC_SOFTWARE        0x95
#define TARGET_EXC_BREAKPOINT      0x96

and in RNBRemote.cpp:

// Translate any mach exceptions to gdb versions, unless they are
// common exceptions like a breakpoint or a soft signal.
switch (tid_stop_info.details.exception.type)
{
    default:                    signum = 0; break;
    case EXC_BREAKPOINT:        signum = SIGTRAP; break;
    case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
    case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
    case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
    case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
    case EXC_SOFTWARE:
        if (tid_stop_info.details.exception.data_count == 2 &&
            tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
            signum = tid_stop_info.details.exception.data[1];
        else
            signum = TARGET_EXC_SOFTWARE;
        break;
}
Hailei
  • 42,163
  • 6
  • 44
  • 69
  • :) thanks for replying! i'm writing my "module" from this tutorial and as i already commented my question earlier i'm already handling SIGSEV and SIGBUS but with no luck. i still can't handle EXC_BAD_ACCESS... try reading comments within that tutorial on cocoa with love... few people are having the same problem as me ... – animal_chin Apr 25 '12 at 12:53
  • THANKS! really! :) this obviously can be a solution to this problem...but i'm sort of confused now, since i'm kind of a newbie to this, how can i handle it? :) calling signal(0x91, /*handler) didn't help... i must look stupid now :) – animal_chin Apr 25 '12 at 13:28
  • Sorry to hear that signal(0x91, handler) doesn't work... I am not sure how do these "fake BSD signal numbers" actually work, especially when debugging (since the debugger may do something, like interrupting, etc.) Did you try this in Xcode or on device? – Hailei Apr 25 '12 at 13:46
  • I found some people say that `EXC_BAD_ACCESS` might be `SIGKILL` signal also. But in the article of Cocoa with Love, it is mentioned that `There are two signals which cannot be caught: SIGKILL and SIGSTOP. These are sent to your application to end it or suspend it without notice.` And I also noticed that if you want to test signal handling properly, you'll need to run without gdb (run with breakpoints off). Did you run the app directly on the device or via USB cable by Xcode? – Hailei Apr 26 '12 at 13:28
  • 1
    PLCrashReporter handles these signals: SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGSEGV,SIGTRAP, see http://code.google.com/p/plcrashreporter/source/browse/trunk/Source/PLCrashSignalHandler.m. And according to http://www.mugginsoft.com/content/how-crash-cocoa-app-testing-purposes-abnormal-termination I guess that `EXC_BAD_ACCESS` only transforms to `SIGSEGV` or `SIGBUS` by UNIX-like OS. – Hailei Apr 26 '12 at 13:48
  • 5
    It's working! :) Thank you very much... :) the problem really was with running the app with gdb, when i disconnected it from xcode and run it on iphone alone it catched EXC_BAD_ACCESS signal properly. Another problem is that 1 EXC_BAD_ACCES generates aprox. 30 signals which are all the same, so i'll have to reduce it to just 1. But that will be ok. So once again...thank you for your time, you really helped me a lot :) – animal_chin Apr 27 '12 at 09:28
  • I just wanted to thank you all for this discussion. I was trying to figure out why my C command line application is not handling the `SIGFPE` signal and always stopping with `EXC_ARITHMETIC` in LLDB in Xcode. Running the executable directly in terminal instead of inside Xcode (without LLDB) worked perfectly :). – alobaili Sep 06 '20 at 20:44