1. 符号表是什么?

符号表就是指在Xcode项目编译后,在编译生成的二进制文件.app的同级目录下生成的同名的.dSYM文件。
.dSYM文件其实是一个目录,在子目录中包含了一个16进制的保存函数地址映射信息的中转文件,所有Debug的symbols都在这个文件中(包括文件名、函数名、行号等),所以也称之为调试符号信息文件。
一般地,Xcode项目每次编译后,都会生成一个新的.dSYM文件。因此,App的每一个发布版本,都需要备份一个对应的.dSYM文件,以便后续调试定位问题。
注意:
项目每一次编译后,.app和.dSYM成对出现,并且二者有相同的UUID值,以标识是同一次编译的产物。
UUID值可以使用dwarfdump —uuid来检查:
$ dwarfdump --uuid XX.app.dSYM#获取.dsym文件的UUID,值可能包含armv7/arm64两组
$ dwarfdump --uuid XX.app/XX#获取.app文件的UUID,值可能包含armv7/arm64两组
那么,问题就来了!

2. 符号表有什么用?

在Xcode开发调试App时,一旦遇到崩溃问题,开发者可以直接使用Xcode的调试器定位分析。
但如果App发布上线,开发者不可能进行调试,只能通过分析系统记录的崩溃日志来定位问题,在这份崩溃日志文件中,会指出App出错的函数内存地址,而这些函数地址是可以在.dSYM文件中找到具体的文件名、函数名和行号信息的,这正是符号表的重要作用所在。
实际上,使用Xcode的Organizer查看崩溃日志时,也自动根据本地存储的.dSYM文件进行了符号化的操作。
并且,崩溃日志也有UUID信息,这个UUID和对应的.dSYM文件是一致的,即只有当三者的UUID一致时,才可以正确的把函数地址符号化。

3. 符号表怎么生成?

一般地,Xcode项目默认的配置是会在编译后生成.dSYM,开发者无需额外修改配置。
项目的Build Settings的相关配置如下:
Generate Debug Symbols = Yes
Debug Information Format = DWARF with dSYM File
采用不同的编译打包方式,产生的.dSYM文件的路径也不相同。
#下面是几种常用的编译打包方式:
1、使用xcodebuild编译打包
在Xcode中编译项目后,会在工程目录下的build/ConfigurationName-iphoneos目录下生成.app和.app.dSYM文件。
如果使用xcodebuild命令进行编译打包,则可以指定编译结果的存储路径,同样会有.app和.app.dSYM生成。
一般地,我们推荐打包发布时,使用xcodebuild编译打包,方便.app和.app.dSYM的匹配存储,避免.app.dSYM文件丢失的情况。
2、使用Xcode的Archive导出
如果开发者使用Xcode的Archive导出功能打包,可以切换到Organizer的Projects视图,查看对应项目的Derived Data路径,在其中可以找到当前导出过程产生的.app和.app.dSYM文件
3、使用make编译打包
如果开发团队不使用Xcode编译打包,而是使用make编译生成.o文件,然后打包发布。此时,编译过程不会有.dSYM文件生成。开发者可以使用dsymutil工具从.o文件中提取符号信息。
4. 符号表怎么用?
在前面的内容可以知道,符号表的作用是把崩溃中的函数地址解析为函数名等信息。
如果开发者能够获取到崩溃的函数地址信息,就可以利用符号表分析出具体的出错位置。
Xcode提供了几个工具来帮助开发者执行函数地址符号化的操作。
例如,崩溃问题的函数地址堆栈如下:
错误地址堆栈
3 CoreFoundation 0x254b5949 0x253aa000 + 1096008
4 CoreFoundation 0x253e6b68 _CF_forwarding_prep_0 + 24
5 SuperSDKTest 0x0010143b 0x000ef000 + 74808
符号化堆栈
3 CoreFoundation 0x254b5949 + 712
4 CoreFoundation 0x253e6b68 _CF_forwarding_prep_0 + 24
5 SuperSDKTest 0x0010143b -[ViewController didTriggerClick:] + 58
说明:
大部分情况下,开发者能获取到的都是错误地址堆栈,需要利用符号表进一步符号化才能分析定位问题。
部分情况下,开发者也可以利用backtrace看到符号化堆栈,可以大概定位出错的函数、但却不知道具体的位置。通过利用符号表信息,也是可以进一步得到具体的出错位置的。
目前,许多崩溃监控服务都显示backtrace符号化堆栈,增加了可读性,但分析定位问题时,仍然要进一步符号化处理。
崩溃信息的UUID
0xef000 - 0x17efff SuperSDKTest armv7 <38d66f9734ca3843a2bf628bb9015a8b> /var/mobile/…/SuperSDKTest.app/SuperSDKTest

下面,利用以下三个工具来进行一下符号化的尝试:

方法1 使用XCode
这种方法可能是最容易的方法了。
要使用Xcode符号化 crash log,你需要下面所列的3个文件:
crash报告(.crash文件)
符号文件 (.dsymb文件)
应用程序文件 (appName.app文件,把IPA文件后缀改为zip,然后解压,Payload目录下的appName.app文件), 这里的appName是你的应用程序的名称。
把这3个文件放到同一个目录下,打开Xcode的Window菜单下的organizer,然后点击Devices tab,然后选中左边的Device Logs。
然后把.crash文件拖到Device Logs或者选择下面的import导入.crash文件。
这样你就可以看到crash的详细log了。 如下图:

2、symbolicatecrash
symbolicatecrash是一个将堆栈地址符号化的脚本,输入参数是苹果官方格式的崩溃日志及本地的.dSYM文件,执行方式如下:
$ export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
$ symbolicatecrash XX.crash [XX.app.dSYM] > xx.sym.crash# 如果未输入.dSYM参数,将只解析系统库对应的符号
使用symbolicatecrash工具的限制就在于只能分析官方格式的崩溃日志,需要从具体的设备中导出,获取和操作都不是很方便,而且,符号化的结果也是没有具体的行号信息的,也经常会出现符号化失败的情况。
实际上Xcode的Organizer内置了symbolicatecrash工具,所以开发者才可以直接看到符号化的错误日志。
3、atos
更普遍的情况是,开发者能获取到错误堆栈信息,而使用atos工具就是把地址对应的具体符号信息找到。
atos实际是一个可以把地址转换为函数名(包括行号)的工具,它的执行方式如下:其中要注意architecture,一般为arm64和armv7
$ xcrun atos -o executable -arch architecture -l loadAddress
address …
说明:
loadAddress 表示函数的动态加载地址,对应崩溃地址堆栈中 + 号前面的地址,即0x000ef000
address 表示运行时地址、对应崩溃地址堆栈中第一个地址,即0x0010143b
实际上,崩溃地址堆栈中+号前后的地址相加即是运行时地址,即0x000ef000 + 74808 = 0x0010143b
执行命令查询地址的符号,可以看到如下结果:
$ xcrun atos -o SuperSDKTest.app.dSYM/Contents/Resources/DWARF/SuperSDKTest -arch armv7 -l 0x000ef000
0x0010143b
-[ViewController didTriggerClick:] (in SuperSDKTest) (ViewController.m:35)
开发者在具体的运用中,是可以通过编写一个脚本来实现符号化错误地址堆栈的。

补充:

1.如何获取crash文件的UUID值:(判断.app或者.dsym文件与该crash文件是否匹配)
可以用:
$ grep “appName armv” *crash
或者
$ grep --after-context=2 “Binary Images:” *crash
2.MTJ的崩溃信息解析(新版和旧版):
新版:
(1)包含了ARCH,可以直接查看编译格式
(2)包含UUID,可以直接获取crash文件对应的UUID值
(3)包含ADDR,可以直接获取load address

参考引用:
http://blog.csdn.net/tencent_bugly/article/details/46275773
http://wufawei.com/2014/03/symbolicating-ios-crash-logs/

iOS崩溃日志符号化 UUID获取相关推荐

  1. iOS崩溃日志符号化及NLP聚类实现

    在解决iOS应用线上崩溃时,我们通常要分析崩溃日志来定位原因.线上崩溃日志一般是未符号或部分符号化的日志,是一堆十六进制的内存地址集合,可读性比较差,这对解决问题几乎没有帮助.所以,我们首先需要先对崩 ...

  2. iOS 崩溃日志在线符号化实践

    1. 什么是符号化? 在日常开发中,应用难免会发生崩溃.通常,我们直接从用户导出来的崩溃日志都是未符号化或者部分符号化的,都是一堆十六进制内存地址的集合,可读性较差.未符号化或者部分符号化的崩溃日志对 ...

  3. iOS崩溃日志分析-b

    1名词解释 1.1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID,目的是为了唯一识别这个文件. 1.2. dwarfdump 苹果提供的命令行工具,其中一些功能就是查 ...

  4. ios崩溃日志收集_iOS崩溃与日志分析

    在iOS开发中经常需要靠记录日志来调试应用程序.解决崩溃问题等,整理常用的日志输出和崩溃日志分析. 最新更新:2018-11-30 基于CocoaLumberjack 的 Swift使用封装库 一.崩 ...

  5. 如何看iOS崩溃日志

    重点:Triggered by Thread这句话后边的线程号,快速定位问题出现在那个线程,是否是你的锅:Triggered by Thread所指的线程表示导致异常.崩溃的线程 下边内容转自简书 简 ...

  6. ios崩溃日志收集_漫谈iOS Crash收集框架

    为了能够第一时间发现程序问题,应用程序需要实现自己的崩溃日志收集服务,成熟的开源项目很多,如 KSCrash,plcrashreporter,CrashKit 等.追求方便省心,对于保密性要求不高的程 ...

  7. iOS崩溃日志的分析

    崩溃日志的产生 iOS中运行App过程中如果发生程序崩溃,会生成一个崩溃日志文件.这个文件会保存的特定系统目录下,扩展名是crash.当手机连接到iTunes时,会将该文件同步到电脑上. 在Mac系统 ...

  8. 遭遇Crash文件战:教你如何搞定iOS崩溃日志

    请叫我背景 最近在提交应用到App Store的时候,竟然被拒了两次.那时候心里的想法是,尼玛完蛋了,要被老板开除了,我是不是要失业了.于是乎那两周几乎毛脑子都是为什么Apple你这么狠心,我们明明相 ...

  9. iOS应用崩溃日志分析 iOS应用崩溃日志揭秘

    转自:http://www.raywenderlich.com/zh-hans/30818/ios%E5%BA%94%E7%94%A8%E5%B4%A9%E6%BA%83%E6%97%A5%E5%BF ...

最新文章

  1. Nature指数发榜:中科院总榜夺冠,北大、清华列学术机构Top 10
  2. openfoam linux教程,科学网—Windows10 安装OpenFOAM 教程 - 陈浩的博文
  3. ping无法访问目标主机 0丢失_预渗透之目标识别
  4. 添加高精度计时器测量处理能力
  5. 彼聆智能语音机器人_人工智能2.0时代,创造他们的究竟是谁?
  6. 配置树莓派linux的内核和编译并将镜像拷贝至树莓派
  7. 【UWB】UWB基本定位原理
  8. dms虚拟服务器,取得dms服务器ip
  9. android 命令pm 全称 packagemanager,关于android:PackageManager安装应用笔记
  10. MSU转Uniprot转Entrez ID
  11. (百度贴吧发帖)html5,百度贴吧怎么发帖子
  12. eNSP配置路由器IP地址
  13. 轰隆隆-小站 链接目录
  14. DDD(Domain-Driven Design 领域驱动设计) 与产品设计
  15. android APK 解析软件包出现问题 解决办法
  16. Matlab交换行列
  17. Java常用技巧和常见错误扫雷
  18. 管理学博士申请考核经验分享——信息收集篇
  19. Vue浏览器图标修改不起作用
  20. JS网页特效实例:禁止网页放入框架

热门文章

  1. IPGuard客户端卸载命令
  2. python | 批量文件名字汉字转拼音
  3. 珍爱网退费流程?珍爱网怎么退费
  4. 解决win11蓝牙开关不显示问题,没有更新蓝牙驱动
  5. linux下C编程详解
  6. MMD :maximum mean discrepancy(最大平均差异)
  7. 阻容感基础09:电感器原理(3)-电感器参数
  8. 利用 OrthoFinder、IQtree、Notung、iTOL 绘制基因树
  9. Spring boot 解析mp4格式视频交给前端进行播放
  10. 穷查理宝典-----第二章 (芒格的生活、学习决策方法)