卡顿堆栈分析

386 阅读2分钟

什么是DWARF

  • DWARF是一种被众多编译器和调试器使用的用于支持源码级别调试的调试文件格式,该格式是一个固定的数据格式

什么是dSYM

  • dSYM就是按照DWARF格式保存调试信息的文件,也就是说,dSYM是一个文件

虚拟内存地址还原成符号

  • 卡顿堆栈

    image.png

    DoraemonKitDemo 内存地址值为 0x10036d224,在运行过程中,其等于 ASLR + 函数的虚拟地址值

  • 获取本次运行的ASLR值,通过lldb获取

    (lldb) image list
    [  0] 5150BC4F-6CA2-3B9E-A15C-77C88F580C9E 0x0000000100354000 /Users/xingyong/Library/Developer/Xcode/DerivedData/DoraemonKitDemo-cukpwpitpdvbtiaahwrbqybnaasx/Build/Products/Debug-iphoneos/DoraemonKitDemo.app/DoraemonKitDemo 
          /Users/xingyong/Library/Developer/Xcode/DerivedData/DoraemonKitDemo-cukpwpitpdvbtiaahwrbqybnaasx/Build/Products/Debug-iphoneos/DoraemonKitDemo.app.dSYM/Contents/Resources/DWARF/DoraemonKitDemo
    

    可以看出 ASLR = 0x0000000100354000 - 0x0000000100000000(vmsize), 那就可以得出该函数的虚拟地址值为 0x10036d224 - 0x354000(ASLR) = 0x100019224

  • 在 dSYM 文件中查找该地址对应的符号

    dwarfdump --lookup 0x100019224 /Users/xingyong/Library/Developer/Xcode/DerivedData/DoraemonKitDemo-cukpwpitpdvbtiaahwrbqybnaasx/Build/Products/Debug-iphoneos/DoraemonKitDemo.app.dSYM
    

    执行结果:

    /Users/xingyong/Library/Developer/Xcode/DerivedData/DoraemonKitDemo-cukpwpitpdvbtiaahwrbqybnaasx/Build/Products/Debug-iphoneos/DoraemonKitDemo.app.dSYM/Contents/Resources/DWARF/DoraemonKitDemo:	file format Mach-O arm64
    0x00068e3d: Compile Unit: length = 0x00000de9, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00069c2a)
    
    0x00068e48: DW_TAG_compile_unit
                  DW_AT_producer	("Apple clang version 14.0.0 (clang-1400.0.29.102)")
                  DW_AT_language	(DW_LANG_ObjC)
                  DW_AT_name	("/Users/xingyong/Downloads/DoKit-master/iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Performance/DoraemonDemoPerformanceViewController.m")
                  DW_AT_LLVM_sysroot	("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.0.sdk")
                  DW_AT_APPLE_sdk	("iPhoneOS16.0.sdk")
                  DW_AT_stmt_list	(0x0001b816)
                  DW_AT_comp_dir	("/Users/xingyong/Downloads/DoKit-master/iOS/DoraemonKitDemo")
                  DW_AT_APPLE_major_runtime_vers	(0x02)
                  DW_AT_low_pc	(0x0000000100017f3c)
                  DW_AT_high_pc	(0x0000000100019668)
    
    0x000693ac:   DW_TAG_subprogram
                    DW_AT_low_pc	(0x00000001000191b4)
                    DW_AT_high_pc	(0x0000000100019230)
                    DW_AT_frame_base	(DW_OP_reg29 W29)
                    DW_AT_object_pointer	(0x000693c6)
                    DW_AT_name	("-[DoraemonDemoPerformanceViewController anrClick]")
                    DW_AT_decl_file	("/Users/xingyong/Downloads/DoKit-master/iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Performance/DoraemonDemoPerformanceViewController.m")
                    DW_AT_decl_line	(193)
                    DW_AT_prototyped	(true)
    Line info: file 'DoraemonDemoPerformanceViewController.m', line 207, column 1, start file 'DoraemonDemoPerformanceViewController.m', start line 193
    

总结

  • dSYM是一个DWARF格式的文件,DWARF是保存调试信息的一种格式

  • Deployment Postprocessing == YES且strip == All Symbols时,在编译的时候会将所有的本地符号脱掉

  • Deployment Postprocessing == NO 且 Debug Information Format == DWAR with dSYM File时,会在编译后生成 dSYM。

  • 根据 偏移后的内存地址值 和 ASLR可以得到 函数的真实虚拟地址值,根据真实虚拟地址值可以在dSYM文件中获取其调试信息。

参考

iOS的调试文件dSYM与DWARF

符号表管理

DoKit/issues