EXC_BAD_ACCESS自动处理

14

我正在尝试为iOS构建自己的信号和未捕获异常处理程序。为此,我使用这两个函数:

NSSetUncaughtExceptionHandler(/*handler*/); 
并且
signal(/*signal const*/, /*signal handler*/);

我的问题是,我无法处理EXC_BAD_ACCESS信号。是否有一些信号常量(例如SIGABRT、SIGBUS)可以捕获EXC_BAD_ACCESS?如果没有,我该如何处理它?一些崩溃分析工具(如PLCrashReporter、Crashlytics等)可以跟踪它...


1
请查看此帖子:https://dev59.com/_EjSa4cB1Zd3GeqPFW0E - Lefteris
好的,我已经包含了SIGSEGV,但它仍然无法捕获EXC_BAD ACCESS :/ 嗯......但还是谢谢你的评论! :) - animal_chin
1个回答

9

EXC_BAD_ACCESS不会生成异常,因此您的第一个函数无法处理该情况。它会生成信号SIGSEGVSIGBUS

请参考Cocoa with Love的Handling unhandled exceptions and signals

更新

我刚刚检查了LLDB的源代码。它可能是TARGET_EXC_BAD_ACCESS= 0x91。

在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

而在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;
}

谢谢回复!我正在根据这个教程编写我的“模块”,并且正如我之前已经评论过的那样,我已经处理了SIGSEV和SIGBUS,但是没有成功。我仍然无法处理EXC_BAD_ACCESS...尝试阅读有关Cocoa with Love的教程中的评论...一些人和我一样遇到了同样的问题... - animal_chin
谢谢!真的! :) 这显然可以解决这个问题...但我现在有点困惑,因为我是一个新手,我该怎么处理呢? :) 调用 signal(0x91, /*handler) 没有帮助...我现在看起来很蠢 :) - animal_chin
很抱歉听到信号(0x91, handler)无法工作...我不确定这些“假的BSD信号编号”实际上是如何工作的,特别是在调试时(因为调试器可能会执行某些操作,如中断等)。你是在Xcode还是设备上尝试过? - Hailei
1
PLCrashReporter 处理以下信号:SIGABRT、SIGBUS、SIGFPE、SIGILL、SIGSEGV、SIGTRAP,请参见 http://code.google.com/p/plcrashreporter/source/browse/trunk/Source/PLCrashSignalHandler.m。根据 http://www.mugginsoft.com/content/how-crash-cocoa-app-testing-purposes-abnormal-termination 的说法,我猜 EXC_BAD_ACCESS 只会在类 UNIX 操作系统中转换为 SIGSEGVSIGBUS - Hailei
5
运作正常了! :) 非常感谢... :) 问题确实在于使用gdb来运行应用程序,当我将其与xcode断开连接并独自在iPhone上运行时,它就能正确捕获EXC_BAD_ACCESS信号。另一个问题是1个EXC_BAD_ACCES会生成大约30个完全相同的信号,因此我需要将其减少到只有1个,但这没关系。所以再次感谢您的时间,您真的帮了我很多 :) - animal_chin
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接