2009-11-13 45 views
0

我試過使用「PLCrashReport」收集崩潰信息,然後使應用程序更穩定,但事實證明,報告是這樣的(甚至沒有調用堆棧,我想怎麼用它?):這種崩潰報告是無用的嗎?

「Exception:」部分,異常:(null):(null),應該是「exceptionName」和「exceptionReason」,大多數時候都是「null」,不知道爲什麼,有時候會有一個正常值,我覺得不太有用...

墜毀2009-11-13 23點43分04秒+0800 - 信號SIGSEGV(代碼SEGV_ACCERR,地址= 0xffffffffc0f4186b)

  • 例外:(空):(空) - 線程0:

    • 毀損:1
    • 堆棧(54幀):\ n 806128664,\ n 807756495,\ n 816280840,\ n 816247 068,\ n 817901396,\ n 807756495,\ n 816280840,\ n 817911108,\ n 816247068,\ n 816285160,\ n 816406620,\ n 807756495,\ n 806130012,\ n 119241,\ n 812165747,\ n 812164839, \ n 812379009,\ n 818127880,\ n 807885435,\ n 807923065,\ n 818122176,\ n 818130772,\ n 816625560,\ n 816626608,\ n 816627024,\ n 816641892,\ n 816651496,\ n 816654628 \ n \ n 816119156,\ n 816119004,\ n 818227300,\ n 807923363,\ n 816119156,\ n 816119004,\ n 816524332,\ n 816525956,\ n 816521588,\ n 816212028, \ n 816151252,\ n 816147980,\ n 827758796,\ n 827769116,\ n 837343488,\ n 821391952,\ n 807840887,\ n 807836793,\ n 807834407,\ n 827752032,\ n 816118388,\ n816157144,\ n 20421

回答

1

我沒用過但是我很確定你沒有得到任何細節,因爲你有一個分段錯誤,把所有的東西都放到了寄存器中。 PLCrashReport實例無法報告,因爲它與其他所有事件一起死亡。

PLCrashReport實例在應用程序本身內運行,所以如果應用程序崩潰,您將無法獲得任何細節。

+0

謝謝!似乎我需要仔細檢查代碼仔細一遍又一遍...... – springrider 2009-11-15 11:45:22

3

什麼是堆棧跟蹤?

每當你的一個方法被調用時,它會把它放到堆棧上。堆棧跟蹤是一種查找應用程序崩潰的類和方法的方法,它通常會將錯誤縮小爲單行。

當然要做到這一點,堆棧跟蹤需要可讀,而不是整個十六進制數的負載。

退房atos。

爲了防止這種情況再次發生,您可以使用atos解釋此調用堆棧。 請參閱Cocoa Dev wiki的Stack Traces頁面,瞭解如何將這些數字轉換爲有意義的方法的討論和代碼。

你需要弄清楚這種方式與墜機記者。我使用UKCrashReporter,並修改了Uli的代碼,這樣如果有未捕獲的異常,它會將可讀堆棧跟蹤添加到崩潰報告中。

代碼示例

我從ESStackTrace類取靈感,這是我做的:

-(void)logAndSaveStackTrace { 
    NSString *stackTrace = [[self userInfo] objectForKey:NSStackTraceKey]; 
    NSString *atosCommand; 
    if (stackTrace) { 
     // If the stack trace key is present, pull out the addresses and convert to method names using atos. 
     atosCommand = [NSString stringWithFormat:@"/usr/bin/atos -p %d %@ | tail -n +3 | head -n +%d | c++filt | cat -n", 
         [[NSProcessInfo processInfo] processIdentifier], 
         stackTrace, 
         ([[stackTrace componentsSeparatedByString:@" "] count] - 4)]; 

    } else { 
     // If there isn't a stack trace key or it's nil, try and work out the stack using the internal callStackReturn addresses method. 
     NSArray *stackTraceArray = [self callStackReturnAddresses]; 
     atosCommand = [NSString stringWithFormat:@"/usr/bin/atos -p %d %@", 
         [[NSProcessInfo processInfo] processIdentifier], 
         [stackTraceArray componentsJoinedByString:@" "]]; 
    } 

    NSString *readableStackTrace = [ShellTask executeShellCommandSynchronously:atosCommand]; 

    NSString *exceptionMessageForCrashReport = [NSString stringWithFormat:@"An exception of type %s occured.\n%s\nStack trace:\n%@", 
               [[self name] cStringUsingEncoding:NSUTF8StringEncoding], 
               [[self reason] cStringUsingEncoding:NSUTF8StringEncoding], 
               readableStackTrace]; 

    [[NSUserDefaults standardUserDefaults] setObject:exceptionMessageForCrashReport forKey:@"uncaughtExceptionReport"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 

    // Log the exception to the console too. 
    NSLog(@"%@", exceptionMessageForCrashReport); 
} 

依賴嗨!

當然,這種方法的問題之一是你引入了對atos的依賴。我被告知它在10.5和更高版本上作爲標準安裝,但這可能是錯誤的。最終我會做一個安裝程序,如果我的應用程序找不到它,它會添加atos。