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中


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4天前
|
存储 分布式计算 监控
【Flume】Flume 监听日志文件案例分析
【4月更文挑战第4天】【Flume】Flume 监听日志文件案例分析
|
4天前
|
搜索推荐 Android开发 iOS开发
安卓与iOS系统的用户界面设计对比分析
本文通过对安卓和iOS两大操作系统的用户界面设计进行对比分析,探讨它们在设计理念、交互方式、视觉风格等方面的差异及各自特点,旨在帮助读者更好地理解和评估不同系统的用户体验。
33 1
|
4天前
|
Android开发 数据安全/隐私保护 iOS开发
安卓与iOS系统的发展趋势与比较分析
【2月更文挑战第6天】 在移动互联网时代,安卓和iOS系统作为两大主流移动操作系统,各自呈现出不同的发展趋势。本文将从技术角度出发,对安卓和iOS系统的发展方向、特点及未来趋势进行比较分析,以期为读者提供更深入的了解和思考。
46 4
|
4天前
|
存储 监控 NoSQL
【MongoDB 专栏】MongoDB 的日志管理与分析
【5月更文挑战第11天】MongoDB日志管理与分析至关重要,包括系统日志和操作日志,用于监控、故障排查和性能优化。合理配置日志详细程度、存储位置和保留策略,使用日志分析工具提升效率,发现性能瓶颈和安全性问题。日志分析有助于优化查询、调整配置,确保数据安全,并可与其他监控系统集成。面对日志量增长的挑战,需采用新技术如分布式存储和数据压缩来保障存储和传输。随着技术发展,不断进化日志管理与分析能力,以支持MongoDB的稳定高效运行。
【MongoDB 专栏】MongoDB 的日志管理与分析
|
4天前
|
存储 监控 关系型数据库
PHP编写的电脑监控软件:用户登录日志记录与分析
使用PHP编写简单但功能强大的电脑监控软件,记录用户登录日志并进行分析。代码示例展示了如何获取并存储用户IP地址和登录时间到数据库,然后进行登录数据的分析,如计算登录频率和常见登录时间。此外,还介绍了如何通过定时任务自动将监控数据提交到网站,以便实时监控用户活动,提升系统安全性和稳定性。
59 0
|
4天前
|
数据可视化
R语言两阶段最小⼆乘法2SLS回归、工具变量法分析股息收益、股权溢价和surfaces曲面图可视化
R语言两阶段最小⼆乘法2SLS回归、工具变量法分析股息收益、股权溢价和surfaces曲面图可视化
|
4天前
|
机器学习/深度学习 前端开发 数据挖掘
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断(下)
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
223 11
|
4天前
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断2
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
|
4天前
|
机器学习/深度学习 前端开发 数据挖掘
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
|
4天前
|
SQL 存储 监控
日志问题精要:分析与总结
该文档讲述了应用系统日志记录的重要性和规则。主要目的是记录操作轨迹、监控系统状态和回溯故障。日志记录点包括系统入口、调用其他模块、调用结束、出口和出错时。内容应遵循UTF-8编码,避免敏感信息,按INFO级别记录,及时、完整且安全。日志输出要控制频率和长度,不影响系统性能,并按策略备份和清理。日志等级分为DEBUG、INFO、WARN、ERROR和FATAL。日志文件应有明确目录结构,大小有限制,并定期清理。注意事项包括输出异常堆栈、避免打印对象实例的hashCode、选择合适的日志框架和格式,并支持动态修改日志级别。还要实现链路追踪,确保在多线程环境中正确记录日志。
28 0