質問

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です。ラッパーと#ifdefsを試してC ++にすることもできますが、これはアプリにとって多くの作業であり、C ++例外がクラッシュをキャッチするとは思いません。

2)シグナル+ setjump + longjmp。私はこれがうまくいくと思った...それはそれが設計されているものです。しかし、SEGVエラーハンドラーを設定し(実際、すべての信号に対して設定しました!)、クラッシュ中に呼び出されることはありません。 raise(SEGV)を呼び出すときに、手動でテスト(および成功)できます。しかし、クラッシュは実際にそれを呼び出していないようです。私の考えは、CFMアプリケーションは完全なBSD信号にアクセスできず、サブセットのみであり、MachアプリケーションはReal Thingに必要であるということです。

3)MPSetExceptionHandler。十分に文書化されていません。ハンドラーを設定しようとしました。コンパイルして実行しましたが、セグメンテーション違反を検出しませんでした。

役に立ちましたか?

解決

SIGSEGVではなくSIGBUSを取得しているのですか?

以下は、メモリ位置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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top