0

我尝试使用“PLCrashReport”来收集崩溃信息,然后使应用程序更稳定,但结果报告是这样的(甚至没有调用堆栈,我想如何使用它?):

“Exception:”部分,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 816247168,\n 816247168,\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 816654224,\n 146455,\n 807923363,\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
4

2 回答 2

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 的小安装程序。

于 2009-12-03T08:26:49.767 回答
1

我没有使用它,但我很确定你没有得到任何细节,因为你有一个分段错误,将所有内容都取出到寄存器中。PLCrashReport 实例无法报告,因为它与其他所有内容一起死亡。

PLCrashReport 实例在应用程序本身内运行,因此如果应用程序出现故障,您将无法获得任何详细信息。

于 2009-11-13T20:46:41.533 回答