【问题标题】:Exception wrapper for Carbon C app in OSXOSX 中 Carbon C 应用程序的异常包装器
【发布时间】: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。没有很好的记录。我试图设置一个处理程序。它编译并运行,但没有捕获段错误。

【问题讨论】:

    标签: c macos exception crash macos-carbon


    【解决方案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
    

    【讨论】:

    • 是的。我认为关键是要捕获每种类型的每个异常!
    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    相关资源
    最近更新 更多