代码之家  ›  专栏  ›  技术社区  ›  SPWorley

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

  •  3
  • SPWorley  · 技术社区  · 17 年前

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

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

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

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

    以下是我的实验:

    1)C++异常。我不确定C++异常是否会捕获SeGebug崩溃。我的应用程序现在是C。我可以尝试包装器和γIFIFS使之成为C++,但这对于应用程序来说是很多工作,我不认为C++异常会导致崩溃。

    2)信号+setjump+longjmp。我以为这会奏效…这就是它的设计目的。但我设置了我的SEGV错误处理程序[事实上,我为每个信号都设置了它!]在撞车的时候从来没有打过电话。我可以在调用raise(segv)时手动测试(并成功)。但车祸似乎并不是真的。我的想法是,CFM应用程序不能访问完整的BSD信号,只有一个子集,并且马赫应用程序对于真实事物是必要的。

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

    1 回复  |  直到 17 年前
        1
  •  3
  •   diciu    17 年前

    你确定你没有得到一个信号总线,而不是一个信号发生器?

    由于尝试在内存位置0写入而导致以下捕获sigbus:

    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