热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS崩溃解析&原理介绍

1.为什么崩溃日志需要解析如图所示是崩溃日志线程回溯信息,其中的调用堆栈都是二进制地址,而不是可读的函数名称因此需要对崩溃日志进行解析,解析成可以理解的函数调用堆栈。

1. 为什么崩溃日志需要解析

如图所示是崩溃日志线程回溯信息,其中的调用堆栈都是二进制地址,而不是可读的函数名称因此需要对崩溃日志进行解析,解析成可以理解的函数调用堆栈。

iOS崩溃解析&原理介绍
image

2.生成dSYM符号文件

crashlog 解析需要调试符号表文件 dSYM(debugging symbols)dSYM 文件实际上是从Mach-O 文件抽取调试信息得到的文件目录。在编译工程时, debug 模式会默认选中生成dSYM文件, 该配置可在 Build Setting|Build Option 中更改。 dSYM文件生成比较耗时,如果不需要进行 crashlog 解析,可以选择不生成。

iOS崩溃解析&原理介绍
image

2.1 Debug下可以在DeriveData的目录下获取到dSYM文件

iOS崩溃解析&原理介绍
image

2.2 打包的时候可以在生成的.achive目录下找到对应的dSYM文件

iOS崩溃解析&原理介绍
image

2 解析方法

2.1 Xcode 解析

crashlogdSYM 文件和可执行文件放在同一目录下,然后将 crashlog 拖拽至 Devicelog中,右键 Re-symbolicate Log 就能解析。

iOS崩溃解析&原理介绍
image

iOS崩溃解析&原理介绍
image

2.2 使用 symbolicatecrash 命令行解析

  • 1.首先找到symbolicatecrash的路径
    iOS崩溃解析&原理介绍
    image

    通常symbolicatecrash的路径为/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

  • 2.命令行解析
    首先将崩溃日志,dSYM以及symbolicatecrash复制出来放到同一个文件夹,然后cd到当前文件夹
    ,运行如下命令解析./symbolicatecrash temp.crash testxcConfig.app.dSYM > result.log

    iOS崩溃解析&原理介绍
    image
  • 3.首次运行需要先运行命令export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"

3.解析原理

dSYM 文件介绍

iOS崩溃解析&原理介绍
image

其中真正保存保存数据的是 DWARF 文件, DWARF(Debuging With Arbitrary Format)是ELF 和 Mach-O 等文件格式中用来存储和处理调试信息的标准格式。 DWARF 中的数据是高度 压 缩 的 , 可以通过dwarfdump命令提取可读信息,比如提取关键的调试信息.debug_info、.debug_line。
注释: ELFMach-O用于存储二进制文件、可执行文件、目标代码和共享库的格式文件。

iOS崩溃解析&原理介绍
image

解析流程

  1. 计算崩溃地址对应符号表中的地址
    以某 crashlog 文件为例,如下图所示。是一个Exception类型的异常,从下至上依次为该线程的调用堆栈,右边红色框第一列为运行时的堆栈地址,第二列为进程运行时的起始地址(testxcConfig 所有行起始地址都相同),第三列为运行时的偏移地址。

    iOS崩溃解析&原理介绍
    image

    运行时堆栈地址=运行时起始地址+偏移地址,以第 4 行为例。0x1022cd990=0x1022c8000 + 0x5990(22928),以上地址均为 app 发生崩溃时的运行地址,根据虚拟内存偏移地址不变的原理,只要知道符号表 TEXT 段的起始地址,加上偏移量(0x5990)就能得到崩溃地址对应符号表中的地址, 符号表 TEXT 段的起始地址可通过以下命令获得。

    iOS崩溃解析&原理介绍
    image

    那么崩溃地址(0x1022cd990)对应符号表中的地址为:0x100005990 =0x0000000100000000+0x5990

  2. 地址重映射
    获取符号表地址后,在 debug-info 章节中查找包含该地址的 DIE(Debug Information Entry)单元就能获知该符号地址对应的函数名称(name)、 函数所在的文件路径(decl file)和函数所在行数(decl line),如下图所示。

    iOS崩溃解析&原理介绍
    image

    上述步骤解析出了函数相关信息, 下面进一步获取该地址对应的准确行数, 这需要借助debug_line章节, debug_line 章节以文件为单位,准确记录了文件中的每一行对应的符号表地址, 0x100005990 对应 AppDelegate.m 的第 20 行。

    iOS崩溃解析&原理介绍
    image
  3. 手动解析 crashlog
    当有完整的 crashlog 文件和对应的 dSYM 文件时,以上过程可以由 Xcode 自动完成。但对于用户反馈的 crash, 需要用户手动复制本地的crashlog 文件,而通常crashlog 文本较长,完整复制其实比较麻烦,那么此时可以只复制崩溃线程的 crash 信息,并通过手动解析。手动解析 crash 可以使用 dwarfdump、 atos 工具, 命令如下。
  • 方法一

    iOS崩溃解析&原理介绍
    image
  • 方法二

    iOS崩溃解析&原理介绍
    image
  • 方法三
    iOS崩溃解析&原理介绍
    image

    方法二、三都使用了atos解析,区别是方法三不需要获取符号表地址, 其后倒数第一个地址为运行时堆栈地址,倒数第二个地址为进程起始地址。
    手动解析另一个应用场景是,若开发人员为了跟进某一偶现问题在日志中记录的是运行时的二进制地址,那么可以通过对应的 dSYM 文件手动解析出调用函数明文。

4.常见问题

  1. 如何找到crashlog 对应的 dSYM 文件?
    打开终端,使用以下命令获取 dSYM 文件对应的 uuid, 并与crashlog文件Binary Image后面的字符对比,如果字符完全相同,就说明 dSYM文件与crashlog对应。

    iOS崩溃解析&原理介绍
    image

    iOS崩溃解析&原理介绍
    image

    另外可以使用mdfind命令去寻找指定uuid的dSYM文件,如下,uuid需大写并转化成格式,如下图
    mdfind "com_apple_xcode_dsym_uuids == D5644244-F2C4-3C96-BD63-EF0F4DA518FA"

    iOS崩溃解析&原理介绍
    image
  2. 如何手动生成 dSYM 文件?
    如果在编译之前忘记在 buildsetting 中选中生成 dSYM文件,然而 app 又发生了崩溃,那么可以通过 app 的可执行文件再手动生成 dSYM 文件。
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil /Users/ranjingfu/Desktop/testxcConfig/testxcConfig.app/testxcConfig -o out.dSYM

    iOS崩溃解析&原理介绍
    image

    值得注意的是,只有可执行文件为 debug 模式产物时,才能使用上述方式手动抽取调试符号表文件(dSYM)release模式无法抽取。 因为debug产物会保存调试信息,而release产物不会, dSYM文件就是从调试信息中抽取出来的。

解析后的崩溃日志实例

iOS崩溃解析&原理介绍
image

推荐阅读
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • 我有一个从C项目编译的.o文件,该文件引用了名为init_static_pool ... [详细]
  • 通过将常用的外部命令集成到VSCode中,可以提高开发效率。本文介绍如何在VSCode中配置和使用自定义的外部命令,从而简化命令执行过程。 ... [详细]
  • 在 CentOS 6.4 上安装 QT5 并启动 Qt Creator 时,可能会遇到缺少 GLIBCXX_3.4.15 的问题。这是由于系统中的 libstdc++.so.6 版本过低。本文将详细介绍如何通过更新 GCC 版本来解决这一问题。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 在 Ubuntu 中遇到 Samba 服务器故障时,尝试卸载并重新安装 Samba 发现配置文件未重新生成。本文介绍了解决该问题的方法。 ... [详细]
  • 如何在Linux服务器上配置MySQL和Tomcat的开机自动启动
    在Linux服务器上部署Web项目时,通常需要确保MySQL和Tomcat服务能够随系统启动而自动运行。本文将详细介绍如何在Linux环境中配置MySQL和Tomcat的开机自启动,以确保服务的稳定性和可靠性。通过合理的配置,可以有效避免因服务未启动而导致的项目故障。 ... [详细]
  • 本文深入探讨了MDK链接脚本的应用与优化技巧。首先,文章介绍了链接脚本的基本概念及其在嵌入式系统开发中的重要性。接着,通过具体实例详细分析了链接脚本的结构和功能,特别是在程序在FLASH中运行时,如何优化链接脚本以提高系统性能。此外,文章还讨论了无需将程序加载到SRAM中的技术细节,为开发者提供了实用的参考和指导。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 本文详细介绍了在Linux系统上编译安装MySQL 5.5源码的步骤。首先,通过Yum安装必要的依赖软件包,如GCC、GCC-C++等,确保编译环境的完备。接着,下载并解压MySQL 5.5的源码包,配置编译选项,进行编译和安装。最后,完成安装后,进行基本的配置和启动测试,确保MySQL服务正常运行。 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • Amoeba 通过优化 MySQL 的读写分离功能显著提升了数据库性能。作为一款基于 MySQL 协议的代理工具,Amoeba 能够高效地处理应用程序的请求,并根据预设的规则将 SQL 请求智能地分配到不同的数据库实例,从而实现负载均衡和高可用性。该方案不仅提高了系统的并发处理能力,还有效减少了主数据库的负担,确保了数据的一致性和可靠性。 ... [详细]
author-avatar
qk墨砚轩
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有