2012-11-29 43 views
4

我實現一個Mac應用程序,我想處理以下事件:管理未處理的異常和崩潰的蘋果Cocoa程序

  • 未處理的異常
  • 程序崩潰(內存錯誤DCC)

如果我發現它們,我可以發送詳細資料給我,使用我發現的崩潰Handlers來分析和修復錯誤。唉,我無法弄清楚如何攔截崩潰和異常。

  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

回答

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添加到您的項目。

+0

謝謝。我補充說,爲了測試這個,你必須禁用GDB。如果啓用GDB,你的信號處理程序永遠不會被稱爲 – pierocampanelli

+0

@pierocampanelli我不認爲這是真的,但是我使用LLDB。你使用的是什麼版本的Xcode? – trojanfoe

+0

4.5.2我正在使用GDB。我需要禁用調試設置調試器爲無。 – pierocampanelli