如何在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 ++异常是否会捕获段错误。我的应用程序目前是C.我可以尝试使用包装器和#ifdef来使它成为C ++但是这对应用程序来说是很多工作,我不认为C ++异常会抓住崩溃。

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

3)MPSetExceptionHandler。没有详细记录。我试图设置一个处理程序。它编译并运行,但没有发现段错误。

有帮助吗?

解决方案

你确定你没有获得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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top