OSX 中 Carbon C 应用程序的异常包装器

Posted

技术标签:

【中文标题】OSX 中 Carbon C 应用程序的异常包装器【英文标题】:Exception wrapper for Carbon C app in OSX 【发布时间】:2010-10-11 12:17:09 【问题描述】:

如何在 OSX Carbon 应用程序中有效地捕获和处理来自 C 的分段错误?

背景:我正在制作一个 OSX Carbon 应用程序。我必须从第三方调用库函数。由于线程问题,该函数偶尔会崩溃,通常是因为它从一个线程更新自身,并且当我从另一个线程查询它时,它有一些内部过时的指针或句柄。该功能对我来说是一个黑匣子。我希望能够调用该函数,但能够“捕获”它是否崩溃并提供替代返回。 在 Windows 中,我可以使用简单的 Visual C 和 Intel C 编译器的 __try 和 __except。

/* Working Windows Example */
__try  x=DangerousFunction(y);
__except(EXCEPTION_EXECUTE_HANDLER) x=0.0; /* whups, func crashed! */

我正在尝试为 OSX 制作相同类型的崩溃捕捉器。我在一个非常大的应用程序上使用纯 C。我每秒调用该函数数百万次,因此效率也非常重要。 (令人印象深刻的是,Windows __try() 开销非常小!)

这是我尝试过的:

1) C++ 异常。我不确定 C++ 异常是否会捕获 segfault 崩溃。我的应用目前是 C。我可以尝试使用包装器和#ifdefs 使其成为 C++,但这对应用来说是很多工作,而且我认为 C++ 异常不会导致崩溃。

2) 信号 + setjump + longjmp。我认为这会起作用......这就是它的设计目的。但是我设置了我的 SEGV 错误处理程序 [实际上我为每个信号都设置了它!] 并且在崩溃期间它从未被调用过。我可以在调用 raise(SEGV) 时手动测试(并成功)。但崩溃似乎并没有真正调用它。我的想法是 CFM 应用程序无法访问完整的 BSD 信号,只有一个子集,并且 Mach 应用程序对于 Real Thing 是必需的。

3) MPSetExceptionHandler。没有很好的记录。我试图设置一个处理程序。它编译并运行,但没有捕获段错误。

【问题讨论】:

【参考方案1】:

你确定你得到的不是 SIGBUS,而是 SIGSEGV?

以下捕获 SIGBUS 是由于尝试在内存位置 0 写入引起的:

cristi:tmp diciu$ cat test.c

#include <signal.h>

static void sigac(int sig)

    printf("sig action here, signal is %d\n", sig);
    exit(1);


int main()

    (void)signal(SIGSEGV, sigac);
    (void)signal(SIGBUS, sigac);

    printf("Raising\n");
    strcpy(0, "aaksdjkajskd|");




cristi:tmp diciu$ ./a.out 
Raising
sig action here, signal is 10

【讨论】:

是的。我认为关键是要捕获每种类型的每个异常!

以上是关于OSX 中 Carbon C 应用程序的异常包装器的主要内容,如果未能解决你的问题,请参考以下文章

OSX 10.9 Mavericks 钥匙串 API 坏了?

什么是 Cocoa,和 Objective-C 有什么关系

Xamarin IOS LexDB Save - 尝试 JIT 编译的异常(包装器委托调用)

osx上的c ++未捕获异常

用 C/C++ 包装 Mac OS X 特定代码的宏

访问 Cocoa 和/或 Carbon 以在 OS X 上自动启动(在 C++ 上也使用 QT)