4

私は Mac アプリを実装しており、次のイベントを処理したいと考えています。

  • 未処理の例外
  • プログラムのクラッシュ (メモリ エラー dcc)

それらを検出した場合は、見つけたクラッシュハンドラーの 1 つを使用してバグを分析および修正するために、詳細を私に送信できます。残念ながら、クラッシュと例外をインターセプトする方法がわかりません。

  1. 最初の質問: 例外とクラッシュを区別する必要がありますか? それとも例外を検出するだけで十分ですか?
  2. 例外やクラッシュをキャッチしてハンドラーにリダイレクトするにはどうすればよいですか?

PS MyApp クラスでフォローしようとしました

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);

しかし、うまくいきません。クラッシュするたびに、SignalHandler または uncaughtExceptionHandler をクラス化せずにデバッガーに移動します。

4

1 に答える 1

3

メソッドの例外をキャッチできるようにするため、単純な例外処理デリゲート クラスを作成するのが最善の方法であることがわかりましたIBAction

main.mm:

@interface ExceptionDelegate : NSObject
@end
static ExceptionDelegate *exceptionDelegate = nil; 


int main(int argc, char **argv)
{
    int retval = 1;

    @autoreleasepool
    {
        //
        // Set exception handler delegate
        //
        exceptionDelegate = [[ExceptionDelegate alloc] init];
        NSExceptionHandler *exceptionHandler = [NSExceptionHandler defaultExceptionHandler];
        exceptionHandler.exceptionHandlingMask = NSLogAndHandleEveryExceptionMask;
        exceptionHandler.delegate = exceptionDelegate;

        //
        // Set signal handler
        //
        int signals[] =
        {
            SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT, SIGFPE, SIGBUS, SIGSEGV,
            SIGSYS, SIGPIPE, SIGALRM, SIGXCPU, SIGXFSZ
        };
        const unsigned numSignals = sizeof(signals) / sizeof(signals[0]);
        struct sigaction sa;
        sa.sa_sigaction = signalHandler;
        sa.sa_flags = SA_SIGINFO;
        sigemptyset(&sa.sa_mask);
        for (unsigned i = 0; i < numSignals; i++)
            sigaction(signals[i], &sa, NULL);

        ....
    }

    ....

    return retval;    
}


static void signalHandler(int sig, siginfo_t *info, void *context)
{
    logerr(@"Caught signal %d", sig);
    exit(102);
}

@implementation ExceptionDelegate

- (BOOL)exceptionHandler:(NSExceptionHandler *)exceptionHandler
      shouldLogException:(NSException *)exception
                    mask:(unsigned int)mask
{
    logerr(@"An unhandled exception occurred: %@", [exception reason]);
   return YES;
}

- (BOOL)exceptionHandler:(NSExceptionHandler *)exceptionHandler
   shouldHandleException:(NSException *)exception
                    mask:(unsigned int)mask
{
    exit(101);

    // not reached
    return NO;
}

@end

プロジェクトに ExceptionHandling.framework を追加する必要があります。

于 2012-11-29T08:13:55.147 に答える