UnCaughtException处理程序:解码回溯符号



我正在尝试获得像Xcode listout这样的反向跟踪符号

*** First throw call stack:
(
    0   CoreFoundation                      0x018865e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x016098b6 objc_exception_throw + 44
    2   CoreFoundation                      0x01923903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
    3   CoreFoundation                      0x0187690b ___forwarding___ + 1019
    4   CoreFoundation                      0x018764ee _CF_forwarding_prep_0 + 14
    5   Foundation                          0x0124036c __NSFireDelayedPerform + 372
    6   CoreFoundation                      0x01844c46 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
    7   CoreFoundation                      0x0184462d __CFRunLoopDoTimer + 1181
    8   CoreFoundation                      0x0182c698 __CFRunLoopRun + 1816
    9   CoreFoundation                      0x0182bb33 CFRunLoopRunSpecific + 467
    10  CoreFoundation                      0x0182b94b CFRunLoopRunInMode + 123
    11  GraphicsServices                    0x02c249d7 GSEventRunModal + 192
    12  GraphicsServices                    0x02c247fe GSEventRun + 104
    13  UIKit                               0x0037c94b UIApplicationMain + 1225
    14  CrashHandler                        0x000088ad main + 141
    15  libdyld.dylib                       0x06244725 start + 0
    16  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我试图从NSException提取符号,如下面的代码。只有更少的信息可用。

-(void)handleException:(NSException*)exception
{
    [exception callStackSymbols]//I've written this into file.
}

我得到了如下的输出

*** First throw call stack: (
0   CoreFoundation                      0x326bd2bb <redacted> + 186
1   libobjc.A.dylib                     0x3a33b97f objc_exception_throw + 30
2   CoreFoundation                      0x326c0e07 <redacted> + 170
3   CoreFoundation                      0x326bf531 <redacted> + 392
4   CoreFoundation                      0x32616f68 _CF_forwarding_prep_0 + 24
5   Foundation                          0x32fcb277 <redacted> + 450
6   CoreFoundation                      0x326925df <redacted> + 14
7   CoreFoundation                      0x32692291 <redacted> + 272
8   CoreFoundation                      0x32690f01 <redacted> + 1232
9   CoreFoundation                      0x32603ebd CFRunLoopRunSpecific + 356
10  CoreFoundation                      0x32603d49 CFRunLoopRunInMode + 104
11  GraphicsServices                    0x361b62eb GSEventRunModal + 74
12  UIKit                               0x34519301 UIApplicationMain + 1120
13  CrashHandler                        0x0007f421 main + 116
14  libdyld.dylib                       0x3a772b20 <redacted> + 0
)

如何解码<redacted>符号?

参考与理解:

我参考了SO post1, SO post2,但它需要dSYM文件,我们必须像试飞一样手动解码。没有dSYM文件,如何做到这一点?

符码化是将内存地址转换为包含以下全部或部分元素的符号的过程:

  • class name
  • method name
  • file name
  • line number

当在设备上使用应用程序符号作为应用程序二进制的一部分进行符号时,只能检索到class namemethod name。不能用这种方法得到file nameline number

当使用应用程序dSYM进行符号化时,只要在构建应用程序时可用所有信息,就可以获得所有数据。例如,当使用第三方静态库时,这些调用可能会丢失文件名和行号。

<redacted>符号只有在设备上表示系统框架地址时才能显示系统调用。class name和/或method name不显示的原因是iOS内存优化。对此的解释可以在这里找到:https://devforums.apple.com/thread/171264为了表示这些地址,你需要有用于在计算机上创建堆栈跟踪的iOS版本和CPU体系结构的iOS符号,该计算机用于表示报告。

可以将这些符号作为Xcode的一部分或通过将特定iOS版本和CPU架构的设备连接到Xcode,然后将获取这些符号。请注意,例如,对于没有更新SDK的iOS错误修复版本,获取符号的唯一方法是使用设备。

计算机上的符号化可以使用Xcode管理器或手动使用symbolciatecrash.pl脚本(Xcode的一部分)在终端手动完成。

对于Xcode或脚本的符号工作,你需要一个完整的崩溃报告,其中包含比你发布的堆栈跟踪更多的信息。

要使用atos手动表示报告的帧地址,您还需要帧引用的每个二进制文件的加载地址,例如来自Foundation, CoreFoundation, UIKit。所示的堆栈跟踪不提供此信息。这里有多个帖子在StackOverflow如何手动使用atos

如果没有dSYM认证文件,就无法表示跟踪。您可以尝试使用不剥离调试符号的选项来构建代码,但我不确定。

也实现崩溃处理程序是一个非常微妙的任务,我会离开专业的;)但你可以试一试,也许还能学到新东西。

最新更新