美文网首页iOS精选
[译]《iOS Crash Dump Analysis》- 错误

[译]《iOS Crash Dump Analysis》- 错误

作者: iOS成长指北 | 来源:发表于2021-02-07 10:07 被阅读0次

    点赞评论,感觉有用的朋友可以关注笔者公众号 iOS 成长指北,持续更新
    原书为 iOS Crash Dump Analysis Book,已得作者授权,欢迎 star

    在本章中,我们将学习错误的内存崩溃。

    在崩溃报告中,我们可以通过异常类型 EXC_BAD_ACCESS (SIGSEGV)EXC_BAD_ACCESS (SIGBUS)来进行区分。

    我们来看看通过搜索互联网获得的一系列崩溃。

    一般原则

    在操作系统中,管理内存的方法是首先将连续的内存排序为内存页,然后将页面排序为段。 这允许将元数据属性分配给应用于该段内的所有页面的段。这允许我们的程序代码(程序 _TEXT _ )被设置为只读但可执行。提高了性能和安全性。

    SIGBUS(总线错误)表示内存地址已正确映射到进程的地址区间,但不允许进程访问内存。

    SIGSEGV(段冲突)表示存储器地址甚至没有映射到进程地址区间。

    段冲突 (SEGV)崩溃

    fud 崩溃

    fud 程序是私有框架 MobileAccessoryUpdater中的一个未记录的进程。

    在这里,我们显示了macOS上进程 fud的崩溃报告,为了便于演示,该报告已被截断:

    Process:               fud [84641]
    Path:                  /System/Library/PrivateFrameworks/
    MobileAccessoryUpdater.framework/Support/fud
    Identifier:            fud
    Version:               106.50.4
    Code Type:             X86-64 (Native)
    Parent Process:        launchd [1]
    Responsible:           fud [84641]
    User ID:               0
    
    Date/Time:             2018-06-12 08:34:15.054 +0100
    OS Version:            Mac OS X 10.13.4 (17E199)
    Report Version:        12
    Anonymous UUID:        6C1D2091-02B7-47C4-5BF9-E99AD5C45875
    
    Sleep/Wake UUID:       369D13CB-F0D3-414B-A177-38B1E560EEC7
    
    Time Awake Since Boot: 240000 seconds
    Time Since Wake:       47 seconds
    
    System Integrity Protection: enabled
    
    Crashed Thread:        1
      Dispatch queue: com.apple.fud.processing.queue
    
    Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
    Exception Codes:       EXC_I386_GPFLT
    Exception Note:        EXC_CORPSE_NOTIFY
    
    Termination Signal:    Segmentation fault: 11
    Termination Reason:    Namespace SIGNAL, Code 0xb
    Terminating Process:   exc handler [0]
    
    Thread 1 Crashed:: Dispatch queue:
     com.apple.fud.processing.queue
    0   libdispatch.dylib               0x00007fff67fc6cbd
     _dispatch_continuation_push + 4
    1   fud                             0x0000000101d3ce57
     __38-[FudController handleXPCStreamEvent:]_block_invoke + 593
    2   libdispatch.dylib               0x00007fff67fbb64a
     _dispatch_call_block_and_release + 12
    3   libdispatch.dylib               0x00007fff67fb3e08
     _dispatch_client_callout + 8
    4   libdispatch.dylib               0x00007fff67fc8377
     _dispatch_queue_serial_drain + 907
    5   libdispatch.dylib               0x00007fff67fbb1b6
     _dispatch_queue_invoke + 373
    6   libdispatch.dylib               0x00007fff67fc8f5d
     _dispatch_root_queue_drain_deferred_wlh + 332
    7   libdispatch.dylib               0x00007fff67fccd71
     _dispatch_workloop_worker_thread + 880
    8   libsystem_pthread.dylib         0x00007fff68304fd2
     _pthread_wqthread + 980
    9   libsystem_pthread.dylib         0x00007fff68304be9
     start_wqthread + 13
    
    Thread 1 crashed with X86 Thread State (64-bit):
      rax: 0xe00007f80bd22039  rbx: 0x00007f80bd2202e0
        rcx: 0x7fffffffffffffff
        rdx: 0x011d800101d66da1
      rdi: 0x00007f80bd21a250  rsi: 0x0000000102c01000
        rbp: 0x0000700007e096c0
        rsp: 0x0000700007e09670
       r8: 0x0000000102c00010   r9: 0x0000000000000001
         r10: 0x0000000102c01000
         r11: 0x00000f80b5300430
      r12: 0x00007f80ba70c670  r13: 0x00007fff673c8e80
        r14: 0x00007f80bd201e00
        r15: 0x00007f80ba70cf30
      rip: 0x00007fff67fc6cbd  rfl: 0x0000000000010202
        cr2: 0x00007fff9b2f11b8
    
    Logical CPU:     3
    Error Code:      0x00000004
    Trap Number:     14
    

    我们显然有一个不好的内存问题,因为我们有一个EXC_BAD_ACCESS (SIGSEGV)(SIGSEGV)异常。 我们看到的错误代码是 14,在 https://github.com/apple/darwin-xnu 中这属于缺页中断。

    由于 libdispatch是 Apple 开源的,我们甚至可以查找触发崩溃的函数。

    我们看到:

    #define dx_push(x, y, z) dx_vtable(x)->do_push(x, y, z)
    
    DISPATCH_NOINLINE
    static void
    _dispatch_continuation_push(dispatch_queue_t dq,
       dispatch_continuation_t dc)
    {
        dx_push(dq, dc, _dispatch_continuation_override_qos(dq,
     dc));
    }
    

    我们正在从一个有错误内存位置的数据结构中解除内存引用。

    我们可以反汇编问题调用站点的macOS二进制文件/usr/lib/system/libdispatch.dylib

    在这里,我们使用 Hopper 进行脱壳:

    __dispatch_continuation_push:
    0000000000014c69 push       rbx
                                 ; CODE XREF=__dispatch_async_f2+112,
                                 j___dispatch_continuation_push
    0000000000014c6a mov        rax, qword [rdi]
    0000000000014c6d mov        r8, qword [rax+0x40]
    0000000000014c71 mov        rax, qword [rsi+8]
    0000000000014c75 mov        edx, eax
    0000000000014c77 shr        edx, 0x8
    0000000000014c7a and        edx, 0x3fff
    0000000000014c80 mov        ebx, dword [rdi+0x58]
    0000000000014c83 movzx      ecx, bh
    0000000000014c86 je         loc_14ca3
    

    rdi寄存器值似乎有问题,地址为 0x00007f80bd21a250

    我们需要退一步,了解为什么我们有内存访问问题。

    查看堆栈回溯,我们可以看到该程序使用跨进程通信(XPC)来完成其工作。 它有 handleXPCStreamEvent 函数。

    这是一个常见的编程问题,当我们接收到一个数据有效负载时,就会出现解压缩有效负载和解释数据的问题。我们推测反序列化代码中有一个bug。这将给我们一个潜在的坏数据结构,我们取消引用会导致崩溃。

    如果我们是fud程序的作者,我们可以对其进行更新以检查它获得的XPC数据,并确保遵循最佳实践进行数据的序列化/反序列化,例如使用接口定义层生成器。

    LeakAgent 崩溃

    苹果提供了 LeakAgent 程序作为其内存诊断工具的一部分。 它在 Xcode Instruments 中使用。

    以下是崩溃报告, LeakAgent 发生了崩溃,为了便于演示而被截断:

    Incident Identifier: 11ED1987-1BC9-4F44-900C-AD07EE6F7E26
    CrashReporter Key:   b544a32d592996e0efdd7f5eaafd1f4164a2e13c
    Hardware Model:      iPad6,3
    Process:             LeakAgent [3434]
    Path:                /Developer/Library/PrivateFrameworks/
    DVTInstrumentsFoundation.framework/LeakAgent
    Identifier:          LeakAgent
    Version:             ???
    Code Type:           ARM-64 (Native)
    Role:                Unspecified
    Parent Process:      DTServiceHub [1592]
    Coalition:           com.apple.instruments.deviceservice
     [463]
    
    
    Date/Time:           2018-07-19 14:16:57.6977 +0100
    Launch Time:         2018-07-19 14:16:56.7734 +0100
    OS Version:          iPhone OS 11.3 (15E216)
    Baseband Version:    n/a
    Report Version:      104
    
    Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
    Exception Subtype: KERN_INVALID_ADDRESS at
     0x0000000000000000
    VM Region Info: 0 is not in any region.
      Bytes before following region: 4371873792
          REGION TYPE                      START - END
                       [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
          UNUSED SPACE AT START
    --->  
          __TEXT        0000000104958000-0000000104964000
           [   48K] r-x/r-x SM=COW  ...ork/LeakAgent
    
    Termination Signal: Segmentation fault: 11
    Termination Reason: Namespace SIGNAL, Code 0xb
    Terminating Process: exc handler [0]
    Triggered by Thread:  4
    
    Thread 4 name:  Dispatch queue:
    DTXChannel serializer queue [x1.c0]
    Thread 4 Crashed:
    0   libswiftDemangle.dylib          
    0x0000000104f871dc 0x104f70000 + 94684
    1   libswiftDemangle.dylib          
    0x0000000104f8717c 0x104f70000 + 94588
    2   libswiftDemangle.dylib          
    0x0000000104f86200 0x104f70000 + 90624
    3   libswiftDemangle.dylib          
    0x0000000104f84948 0x104f70000 + 84296
    4   libswiftDemangle.dylib          
    0x0000000104f833a4 0x104f70000 + 78756
    5   libswiftDemangle.dylib          
    0x0000000104f73290 0x104f70000 + 12944
    6   CoreSymbolication               
    0x000000019241d638 demangle + 112
    7   CoreSymbolication               
    0x00000001923d16cc
     TRawSymbol<Pointer64>::name+ 54988 () + 72
    8   CoreSymbolication               
    0x0000000192404ff4
     TRawSymbolOwnerData<Pointer64>::
     symbols_for_name(CSCppSymbolOwner*, char const*,
        void + 266228 (_CSTypeRef) block_pointer) + 156
    9   CoreSymbolication               
    0x00000001923d9734
     CSSymbolOwnerGetSymbolWithName + 116
    10  Symbolication                   
    0x000000019bb2e7f4
     -[VMUObjectIdentifier _targetProcessSwiftReflectionVersion]
      + 120
    11  Symbolication                   
    0x000000019bb2f9d8
     -[VMUObjectIdentifier loadSwiftReflectionLibrary] + 36
    12  Symbolication                   
    0x000000019bb29ff0
     -[VMUObjectIdentifier initWithTask:symbolicator:scanner:]
      + 436
    13  Symbolication                   
    0x000000019baede10
     -[VMUTaskMemoryScanner _initWithTask:options:] + 2292
    14  Symbolication                   
    0x000000019baee304
     -[VMUTaskMemoryScanner initWithTask:options:] + 72
    15  LeakAgent                       
    0x000000010495b270 0x104958000 + 12912
    16  CoreFoundation                  
    0x0000000183f82580 __invoking___ + 144
    17  CoreFoundation                  0x0000000183e61748
     -[NSInvocation invoke] + 284
    18  DTXConnectionServices           
    0x000000010499f230 0x104980000 + 127536
    19  DTXConnectionServices           
    0x00000001049947a4 0x104980000 + 83876
    20  libdispatch.dylib               0x000000018386cb24
     _dispatch_call_block_and_release + 24
    21  libdispatch.dylib               0x000000018386cae4
     _dispatch_client_callout + 16
    22  libdispatch.dylib               0x0000000183876a38
     _dispatch_queue_serial_drain$VARIANT$mp + 608
    23  libdispatch.dylib               0x0000000183877380
     _dispatch_queue_invoke$VARIANT$mp + 336
    24  libdispatch.dylib               0x0000000183877d4c
     _dispatch_root_queue_drain_deferred_wlh$VARIANT$mp + 340
    25  libdispatch.dylib               0x000000018388011c
     _dispatch_workloop_worker_thread$VARIANT$mp + 668
    26  libsystem_pthread.dylib         0x0000000183b9fe70
     _pthread_wqthread + 860
    27  libsystem_pthread.dylib         
    0x0000000183b9fb08 start_wqthread + 4
    
    Thread 4 crashed with ARM Thread State (64-bit):
        x0: 0x0000000000000000   x1: 0x0000000000000000   
        x2: 0xfffffffffffffff6
           x3: 0x0000000000000041
        x4: 0x0000000000000000   x5: 0x0000000104f97950   
        x6: 0x0000000000000006
           x7: 0x00000000ffffffff
        x8: 0x00000001050589d0   x9: 0x0000000104f840d8  
        x10: 0xffffffffffffd544
          x11: 0x0000000000000a74
       x12: 0x0000000000000002  x13: 0x00000000000002aa  
       x14: 0x00000000000002aa
         x15: 0x00000000000003ff
       x16: 0x0000000183b96360  x17: 0x0000000000200000  
       x18: 0x0000000000000000
         x19: 0x000000016b6d1ba0
       x20: 0x00000001050589a0  x21: 0x0000000000000000  
       x22: 0x0000000000000000
         x23: 0x0000000000000001
       x24: 0x00000000ffffffff  x25: 0x0000000000000006  
       x26: 0x0000000104f97950
         x27: 0x0000000000000000
       x28: 0x0000000000000009   fp: 0x000000016b6d19c0   
       lr: 0x0000000104f8717c
        sp: 0x000000016b6d1930   pc: 0x0000000104f871dc
        cpsr: 0x60000000
    

    我们可以看到出错的内核地址是0x0000000000000000,所以它是一个空指针解引用。我们崩溃的调用站点是一个分解符号的 Swift 库。Xcode 工具试图从它在 iPad 上看到的活动中提供人类可读的对象类型定义。

    如果我们是用户并视图分析我们的应用程序,然后在LeakAgent中遇到此错误,那么我们需要尝试找出避免该问题的方法。

    由于问题是由于符号化造成的,所以明智的做法是清除构建目录,然后进行一次干净的构建。有时,Xcode更新会将我们切换到不兼容的新目标文件格式。 值得与另一个项目(可能是微不足道的测试程序)一起检查性能。 还有其他内存分析工具,例如我们正在运行的方案的诊断选项,因此可以用不同的方式进行内存分析。 有关更多信息,请参见下一章内存诊断 。

    指针验证机制崩溃

    之前,在 指针验证机制 一章中,我们看到了用户启用指针验证机制会导致崩溃。接下来我们看一些使用指针验证机制的系统库发生的崩溃。

    Incident Identifier: 692E5696-6994-4FB3-B42D-C9317D956EE7
    CrashReporter Key:   1f2cdb7448d354584634e8576c1e5257634fc0cd
    Hardware Model:      iPhone12,1
    Process:             get [1737]
    Path:               
     /private/var/containers/Bundle/Application/2BF678BB-7CC6-4CAC-BF
    49-0298B611F1BA/get.app/get
    Identifier:         
     com.soul.merge.cat.cute.simulator.adventure.get
    Version:             44 (1.4.4)
    AppStoreTools:       11C29
    AppVariant:          1:iPhone12,1:13
    Code Type:           ARM-64 (Native)
    Role:                Foreground
    Parent Process:      launchd [1]
    Coalition:          
     com.soul.merge.cat.cute.simulator.adventure.get [757]
    
    Date/Time:           2019-12-26 09:54:15.6806 +0300
    Launch Time:         2019-12-26 09:43:08.8423 +0300
    OS Version:          iPhone OS 13.3 (17C54)
    Release Type:        User
    Baseband Version:    1.03.12
    Report Version:      104
    
    Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
    Exception Subtype: KERN_INVALID_ADDRESS at 0x41fc821e000001b0 ->
     0xffffff9e000001b0 (possible pointer authentication failure)
    VM Region Info: 0xffffff9e000001b0 is not in any region.  Bytes
     after previous region: 18446743641528467889
          REGION TYPE                      START - END             [
     VSIZE] PRT/MAX SHRMOD  REGION DETAIL
          MALLOC_NANO            0000000280000000-00000002a0000000
     [512.0M] rw-/rwx SM=PRV
    --->
          UNUSED SPACE AT END
    
    Triggered by Thread:  27
    
    Thread 27 name:
    Thread 27 Crashed:
    0   libEmbeddedSystemAUs.dylib          0x00000001d0246644
     InterruptionListener(void*, unsigned int, unsigned int, void
     const*) + 352 (AURemoteIO.cpp:257)
    1   libEmbeddedSystemAUs.dylib          0x00000001d0246578
     InterruptionListener(void*, unsigned int, unsigned int, void
     const*) + 148 (AURemoteIO.cpp:256)
    2   AudioToolbox                        0x00000001bd34e710
     AudioSessionPropertyListeners::CallPropertyListeners(unsigned
     int, unsigned int, void const*) + 596
     (AudioSessionPropertyListeners.cpp:146)
    3   AudioToolbox                        0x00000001bd3ab564
     HandleAudioSessionCFTypePropertyChangedMessage(unsigned int,
     unsigned int, void*, unsigned int) + 1104 (AudioSession.cpp:932)
    4   AudioToolbox                        0x00000001bd3aac1c
     ProcessDeferredMessage(unsigned int, __CFData const*, unsigned
     int, unsigned int) + 2540 (AudioSession.cpp:1050)
    5   AudioToolbox                        0x00000001bd4187e0
     _XAudioSessionPingMessage + 688 (AudioSession.cpp:1161)
    6   libAudioToolboxUtility.dylib        0x00000001bd4a76b4
     mshMIGPerform + 268 (MachServerHelper.c:450)
    7   CoreFoundation                      0x00000001b1f207c4
     __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 60
     (CFRunLoop.c:1937)
    8   CoreFoundation                      0x00000001b1f1fe90
     __CFRunLoopDoSource1 + 448 (CFRunLoop.c:2075)
    9   CoreFoundation                      0x00000001b1f1aac8
     __CFRunLoopRun + 2144 (CFRunLoop.c:3098)
    10  CoreFoundation                      0x00000001b1f19f40
     CFRunLoopRunSpecific + 480 (CFRunLoop.c:3192)
    11  AVFAudio                            0x00000001beeb1f70
     GenericRunLoopThread::Entry(void*) + 160
     (GenericRunLoopThread.h:91)
    12  AVFAudio                            0x00000001bef031fc
     CAPThread::Entry(CAPThread*) + 208 (CAPThread.cpp:286)
    13  libsystem_pthread.dylib             0x00000001b1cad840
     _pthread_start + 168 (pthread.c:896)
    14  libsystem_pthread.dylib             0x00000001b1cb59f4
     thread_start + 8
    
    Thread 27 crashed with ARM Thread State (64-bit):
        x0: 0x0000000000000000   x1: 0x0000000000000000   x2:
     0x0000000000000100   x3: 0x0000000000000000
        x4: 0x00000000000020a0   x5: 0x0000000000000020   x6:
     0x0000000000000000   x7: 0x00000000000003da
        x8: 0x41fc821e00000000   x9: 0x0000000000000020  x10:
     0x0000000000000000  x11: 0x0000000000000202
       x12: 0x0000000000000002  x13: 0x0000000000000000  x14:
     0x0000000000000002  x15: 0x0000000000000001
       x16: 0x00000001b1c6b43c  x17: 0x00000001f0430630  x18:
     0x0000000000000000  x19: 0x0000000103823040
       x20: 0x00000001710287fc  x21: 0x00000000696e7472  x22:
     0x0000000108aa3b28  x23: 0x000000010fd10588
       x24: 0x000000010fd105a0  x25: 0x0000000064696564  x26:
     0x00000001fb421000  x27: 0x00000000006c9000
       x28: 0x0000000000000049   fp: 0x0000000171028660   lr:
     0xe970e981d0246578
        sp: 0x0000000171028600   pc: 0x00000001d0246644 cpsr:
     0x80000000
       esr: 0x56000080  Address size fault
    
    Binary Images:
    0x10005c000 - 0x102687fff get arm64 
     <bde08a08d8cf3e6b8cee8ab2cf246ccb>
     /var/containers/Bundle/Application/2BF678BB-7CC6-4CAC-BF49-0298B
    611F1BA/get.app/get
    .
    .
    0x1d01b7000 - 0x1d02c3fff libEmbeddedSystemAUs.dylib arm64e 
     <48e72efe02243faabf3e1760bb4c2731>
     /System/Library/Frameworks/AudioToolbox.framework/libEmbeddedSys
    temAUs.dylib
    

    这里,我们看到故障地址 0x41fc821e000001b0最高 24 位为41fc82。 这就是 指针校验验证码(PAC)。\index{PAC}

    我们看到故障函数 InterruptionListener 使用两个指针作为参数,并且我们已经将寄存器 x8 的地址设置为0x41fc821e00000000。 因此,大概我们的失败代码正在使用该地址,加上一些小的偏移量 0x1b0。 这可能是由于使用了手动指针算法,导致使用了未经身份验证的指针。

    感谢你阅读本文! 🚀

    相关文章

      网友评论

        本文标题:[译]《iOS Crash Dump Analysis》- 错误

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