美文网首页APP & program
iOS 友盟崩溃日志分析——Thread state

iOS 友盟崩溃日志分析——Thread state

作者: anny_4243 | 来源:发表于2022-12-08 16:52 被阅读0次

    崩溃报告的线程状态部分列出了应用程序终止时崩溃线程的CPU寄存器及其值。了解线程状态是一个高级主题,需要了解应用程序二进制接口(ABI)。

    寄存器为内存访问问题导致的崩溃提供额外信息。了解崩溃线程的寄存器将进一步讨论这种情况。

    大多数崩溃报告的分析不需要考虑寄存器状态。然而,如果您正在调查一个困难的内存访问问题,寄存器会提供崩溃报告中其他地方找不到的信息。

    • 内存访问是内存获取还是指令获取?
    • 程序计数器、链接寄存器和堆栈指针寄存器是否在程序的地址空间中包含有效地址?
    • 如果您使用atos来表示链接寄存器中的地址,它的功能是什么?该函数是否通过函数指针跳转到其他代码?

    确定导致问题的内存访问类型

    内存访问问题有两类:无效内存获取和无效指令获取。当代码取消引用无效指针时,会发生无效内存提取。当函数通过错误的函数指针或通过对意外对象的函数调用跳转到另一个函数时,会发生无效的指令获取。要确定哪种类型的内存访问问题导致了崩溃,请关注程序计数器,这是一个包含导致内存访问异常的指令地址的寄存器。在ARM CPU架构上,这是pc寄存器。在x86_64 CPU架构上,这是rip寄存器。

    如果程序计数器寄存器与异常地址不相同,则崩溃是由于无效的内存获取。例如,考虑x86_64 CPU上的以下macOS崩溃报告:

    Exception Type:  SIGSEGV
    Exception Codes: SEGV_MAPERR at 0x21474feae2c8
    ...
    Thread 12 crashed with X86-64 Thread State:
       rip: 0x00007fff61f5739d    rbp: 0x00007000026c72c0    rsp: 0x00007000026c7248    rax: 0xe85e2965c85400b4 
       rbx: 0x00006000023ee2b0    rcx: 0x00007f9273022990    rdx: 0x00007000026c6d88    rdi: 0x00006000023ee2b0 
       rsi: 0x00007fff358aae0f     r8: 0x00000000000003ff     r9: 0x00006000023edbc0    r10: 0x000021474feae2b0 
       r11: 0x00007fff358aae0f    r12: 0x000060000237af10    r13: 0x00007fff61f57380    r14: 0x00006000023ee2b0 
       r15: 0x0000000000000006 rflags: 0x0000000000010202     cs: 0x000000000000002b     fs: 0x0000000000000000 
        gs: 0x0000000000000000 
    

    程序计数器寄存器(rip)为0x00007fff61f5739d,这与异常的地址0x21474feae2c8不同。此崩溃是由于无效的内存获取。

    如果程序计数器寄存器与异常地址相同,则崩溃是由于无效的指令获取。例如,考虑arm64 CPU上的以下iOS崩溃报告:

    Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
    Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000040
    ...
    Thread 0 name:  Dispatch queue: com.apple.main-thread
    Thread 0 Crashed:
    0   ???                               0x0000000000000040 0 + 64
    ...
    Thread 0 crashed with ARM Thread State (64-bit):
        x0: 0x0000000000000002   x1: 0x0000000000000040   x2: 0x0000000000000001   x3: 0x000000016dcfe080
        x4: 0x0000000000000010   x5: 0x000000016dcfdc8f   x6: 0x000000016dcfdd80   x7: 0x0000000000000000
        x8: 0x000000010210d3c8   x9: 0x0000000000000000  x10: 0x0000000000000014  x11: 0x0000000102835948
       x12: 0x0000000000000014  x13: 0x0000000000000000  x14: 0x0000000000000001  x15: 0x0000000000000000
       x16: 0x000000010210c0b8  x17: 0x00000001021063b0  x18: 0x0000000000000000  x19: 0x0000000102402b80
       x20: 0x0000000102402b80  x21: 0x0000000204f6b000  x22: 0x00000001f6e6f984  x23: 0x0000000000000001
       x24: 0x0000000000000001  x25: 0x00000001fc47b690  x26: 0x0000000102304040  x27: 0x0000000204eea000
       x28: 0x00000001f6e78fae   fp: 0x000000016dcfdec0   lr: 0x00000001021063c4
        sp: 0x000000016dcfdec0   pc: 0x0000000000000040 cpsr: 0x40000000
       esr: 0x82000006 (Instruction Abort) Translation fault
    
    Binary Images:
    0x102100000 - 0x102107fff MyCoolApp arm64  <87760ecf8573392ca5795f0db63a44e2> /var/containers/Bundle/Application/686CA3F1-6CC5-4F84-8126-EE22D03BC161/MyCoolApp.app/MyCoolApp
    

    在本例中,程序计数器寄存器(pc)为0x0000000000000040,它与异常子类型中报告的地址匹配,表明此崩溃是由于错误的指令获取造成的。因为这是一个错误的指令获取,所以回溯中的第0帧不包含正在运行的函数,如“???”所示而不是回溯中的符号名称。然而,链接寄存器lr包含在正常情况下代码在函数调用后返回的位置。链接寄存器中的值允许您跟踪跳转到错误指令指针的原点。

    x86_64 CPU体系结构将返回地址存储在堆栈上,而不是存储在链接寄存器中,因此无法跟踪x86_64处理器上错误函数指针的来源。

    链接寄存器(lr)包含0x00000001021063c4,这是应用程序进程中加载的二进制文件之一中的指令地址。崩溃报告的Binary Images部分显示该地址位于MyCoolApp二进制文件内,因为该地址位于该二进制文件列出的范围0x102100000-0x102107fff内。有了这些信息,您可以使用atos命令行工具和二进制文件的dSYM文件,并识别位于0x00000001021063c4的相应代码:

    % atos -arch arm64 -o MyCoolApp.app.dSYM/Contents/Resources/DWARF/MyCoolApp -l 0x102100000 0x00000001021063c4
    -[ViewController loadData] (in MyCoolApp) (ViewController.m:38)
    

    友盟崩溃日志原文:

    Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
    Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
    
    Thread 0 crashed with ARM-64 Thread State:
      cpsr: 0x0000000080000000     fp: 0x000000016d79a5e0     lr: 0x000000010344156c     pc: 0x0000000102fb28c0 
        sp: 0x000000016d79a5c0     x0: 0x000000016d79a638     x1: 0x0000000000000000    x10: 0x0000000000000000 
       x11: 0x00000000000007fd    x12: 0x0000000000000012    x13: 0x00000000b5804054    x14: 0x00000000b5a04800 
       x15: 0x0000000000000009    x16: 0x00000001ef7ef100    x17: 0x0000000230c58c10    x18: 0x0000000000000000 
       x19: 0x00000001515082e0     x2: 0x0000000230c3f260    x20: 0x877a31c8606f7002    x21: 0x0000000000000002 
       x22: 0x000000014be94140    x23: 0x877a31c86075701a    x24: 0x0000000000000000    x25: 0x0000000000000000 
       x26: 0x0000000000000000    x27: 0x0000000000000000    x28: 0x000000010410b910    x29: 0x000000016d79a5e0 
        x3: 0x00000001e8db62ec     x4: 0x0000000000000000     x5: 0x0000000000000010     x6: 0x0000000000000079 
        x7: 0x0000000000000000     x8: 0x000000016d79a640     x9: 0xab84ca84cec80013 
    
    Binary Images:
           0x102664000 -        0x103d53fff +XXXApp arm64  <c3e2537682e73a81a84d236feea6582c> /private/var/containers/Bundle/Application/89DB2FD2-4411-4A9F-AC8D-635559FF85E7/XXXApp.app/XXXApp
    
    

    分析:
    在本例中,程序计数器寄存器(pc)为0x0000000102fb28c0,这与异常的地址0x21474feae2c8不同。此崩溃是由于无效的内存获取。链接寄存器lr包含在正常情况下代码在函数调用后返回的位置。链接寄存器中的值允许您跟踪跳转到错误指令指针的原点。

    链接寄存器(lr)包含0x000000010344156c,这是应用程序进程中加载的二进制文件之一中的指令地址。崩溃报告的Binary Images部分显示该地址位于XXXApp二进制文件内,因为该地址位于该二进制文件列出的范围0x102664000 - 0x103d53fff内。有了这些信息,您可以使用atos命令行工具和二进制文件的dSYM文件,并识别位于0x000000010344156c的相应代码:

    % atos -o /Users/xx/Library/Developer/Xcode/Archives/2022-12-02/XXXApp\ 2022-12-2\,\ 10.31.xcarchive/dSYMs/XXXApp.app.dSYM/Contents/Resources/DWARF/XXXApp -l 0x1022ac000 0x0000000103042080
    -[MobClickInternal saveAndCleanCache] (in XXXApp) + 804
    

    由此定位到崩溃出现在友盟的SDK中

    参考链接:https://developer.apple.com/documentation/xcode/investigating-memory-access-crashes?language=objc#Identify-the-type-of-memory-access-that-caused-the-issue

    相关文章

      网友评论

        本文标题:iOS 友盟崩溃日志分析——Thread state

        本文链接:https://www.haomeiwen.com/subject/ynjifdtx.html