我有一个 macOS 中 Xcode 应用程序的异常处理框架,其中包含 Cpp 和 Swift 代码。我正在使用 Unix 信号框架通过 sigaction 来处理异常。当出现 swift 或 Cpp 异常时,我的 sigaction 信号处理程序会被调用。然而,对于某些异常(例如 SIGSEGV),信号处理程序会被重复调用。为了处理这个问题,我使用 SA_RESETHAND 标志,以便处理程序仅被调用一次,然后信号的默认操作接管以终止进程。
当由于 Cpp 代码而发生异常时,这种方法效果很好,但是当由于 Swift 代码而发生异常时,信号处理程序仍然会被重复调用。有人可以解释为什么会发生这种情况以及解决方案是什么吗?
我碰巧注意到这个 Cosmopolitan libc 提交解释了这个错误:https://github.com/jart/cosmopolitan/commit/793393a3413f7c7b781fc88750e6c2659af9b56f
苹果的文档 声称支持此功能,但他们只定义了常量 他们的头文件。内核通过以下方式确认 SA_RESETHAND 位: 将其从 sa_flags 状态中清除,返回零,并且不执行任何操作。
您可能可以通过以下方式解决该错误:
int signal_handler(int sig) {
static volatile sig_atomic_t called = 0;
if (called) {
signal(sig, SIG_DFL);
raise(sig);
}
called = 1;
// Your code here
}
仅当您为每个信号使用不同的信号处理函数时,上述方法才能正确工作。