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

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

崩溃报告的线程状态部分列出了应用程序终止时崩溃线程的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中


相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1648 4
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
安全 Android开发 数据安全/隐私保护
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
1122 21
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
311 8
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
5081 32
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
636 9
|
监控 容灾 算法
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
本文探讨了如何高效、经济且可靠地将海外应用与基础设施日志统一采集至阿里云日志服务(SLS),解决全球化业务扩展中的关键挑战。重点介绍了高性能日志采集Agent(iLogtail/LoongCollector)在海外场景的应用,推荐使用LoongCollector以获得更优的稳定性和网络容错能力。同时分析了多种网络接入方案,包括公网直连、全球加速优化、阿里云内网及专线/CEN/VPN接入等,并提供了成本优化策略和多目标发送配置指导,帮助企业构建稳定、低成本、高可用的全球日志系统。
1355 55