转:http://bugly.qq.com/blog/?p=119

iOS崩溃堆栈符号化,定位问题分分钟搞定!

2015.3.16 腾讯Bugly 微信分享
 

最近一段时间,在跟开发者沟通过程中,萝莉发觉大家对iOS的应用符号表还不是很清楚,除了咨询关于符号表生成、配置的问题以外,对Bugly崩溃分析需要配置符号表也存在疑问。

在这里,萝莉就给大家分享下关于iOS符号表的一些内容。

首先,进行常识“脑补”。

1. 符号表是什么?

符号表就是指在Xcode项目编译后,在编译生成的二进制文件.app的同级目录下生成的同名的.dSYM文件。

.dSYM文件其实是一个目录,在子目录中包含了一个16进制的保存函数地址映射信息的中转文件,所有Debugsymbols都在这个文件中(包括文件名、函数名、行号等),所以也称之为调试符号信息文件。

一般地,Xcode项目每次编译后,都会生成一个新的.dSYM文件。因此,App的每一个发布版本,都需要备份一个对应的.dSYM文件,以便后续调试定位问题。

注意:
项目每一次编译后,.app.dSYM成对出现,并且二者有相同的UUID值,以标识是同一次编译的产物。
UUID值可以使用dwarfdump —uuid来检查:

 $ dwarfdump --uuid XX.app.dSYM
$ dwarfdump --uuid XX.app/XX

那么,问题就来了!

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导出

如果开发者使用XcodeArchive导出功能打包,可以切换到OrganizerProjects视图,查看对应项目的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 <redacted> + 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、symbolicatecrash

symbolicatecrash是一个将堆栈地址符号化的脚本,输入参数是苹果官方格式的崩溃日志及本地的.dSYM文件,执行方式如下:

$ symbolicatecrash XX.crash [XX.app.dSYM] > xx.sym.crash# 如果输入.dSYM参数,将只解析系统库对应的符号

使用symbolicatecrash工具的限制就在于只能分析官方格式的崩溃日志,需要从具体的设备中导出,获取和操作都不是很方便,而且,符号化的结果也是没有具体的行号信息的,也经常会出现符号化失败的情况。
实际上XcodeOrganizer内置了symbolicatecrash工具,所以开发者才可以直接看到符号化的错误日志。

2、atos

更普遍的情况是,开发者能获取到错误堆栈信息,而使用atos工具就是把地址对应的具体符号信息找到。

atos实际是一个可以把地址转换为函数名(包括行号)的工具,它的执行方式如下:

$ 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)

开发者在具体的运用中,是可以通过编写一个脚本来实现符号化错误地址堆栈的。

5. 结语

在实际的项目开发中,崩溃问题的分析定位都不是采用这种方式,因为它依赖于系统记录的崩溃日志或错误堆栈,在本地开发调试阶段,是没有问题的。

如果在发布的线上版本出现崩溃问题,开发者是无法即时准确的取得错误堆栈。一般地,开发者都是接入第三方的崩溃监控服务(如腾讯Bugly),实现线上版本崩溃问题的记录和跟踪。

目前,国内外提供崩溃监控服务的产品有好几个,在崩溃问题的统计上可能不分伯仲。但提供自动符号化功能的产品却基本没有,大部分崩溃问题的堆栈只是简单符号化以增强可读性,没有可以快速定位问题的行号信息。

腾讯Bugly提供了地址堆栈符号化功能的崩溃监控服务,只要开发者配置了对应的符号表信息,Bugly服务会自动对错误地址堆栈进行符号化,出错位置清晰可见,分分钟定位和解决崩溃问题。

转: iOS崩溃堆栈符号表使用与用途的更多相关文章

  1. Android&iOS崩溃堆栈上报

    Android&iOS崩溃堆栈上报 原文地址:http://www.cnblogs.com/songcf/p/4885468.html 通过崩溃捕获和收集,可以收集到已发布应用(游戏)的异常, ...

  2. Bugly iOS自动导入符号表

      前言       最近在处理Bugly问题的时候顺便解决了下符号表上传的问题,使用最新的上传工具包,也是顺便整理了下可以使用的脚本添加到了项目中,把这个过程中遇到的问题总结出来,脚本也会给出来,实 ...

  3. iOS 符号表恢复 & 逆向支付宝

    推荐序 本文介绍了恢复符号表的技巧,并且利用该技巧实现了在 Xcode 中对目标程序下符号断点调试,该技巧可以显著地减少逆向分析时间.在文章的最后,作者以支付宝为例,展示出通过在 UIAlertVie ...

  4. iOS - swift项目接入bugly - 报错, 配置符号表,下载Java环境,

    1.pod 安装,无需配置任何东西 2.终端找到路径: pod install 3.在 appdelegate 导入  import Bugly extension AppDelegate{ /// ...

  5. iOS:bugly符号表上传

    https://blog.csdn.net/weixin_38633659/article/details/81667721 这个篇文章已经讲得足够清楚 而且官方的文档也写得很好(注意官方网站上的文档 ...

  6. iOS 崩溃日志 Backtrace的符号化

    iOS的崩溃日志配合dsym文件可以找到崩溃时的backtrace,这是解决崩溃的最重要的信息. 如果是在同一台mac上打包, 导入crash log时候会自动将backtrace符号化,可以看到方法 ...

  7. iOS崩溃调试的使用和技巧总结

    在iOS开发调试过程中以及上线之后,程序经常会出现崩溃的问题.简单的崩溃还好说,复杂的崩溃就需要我们通过解析Crash文件来分析了,解析Crash文件在iOS开发中是比较常见的. 现在网上有很多关于解 ...

  8. bugly cocos 接入和 符号表使用

    bugly cocos 接入和 符号表使用 在bugly网站下载 BuglyCocosPlugin 的sdk ios 1. 在 项目的 classes 里面新建 文件夹  BuglyCocosPlug ...

  9. iOS崩溃日志ips文件解析

    iOS崩溃日志ips文件解析  一 简介 测试组的同事在进行稳定性测试时,通常会遇到一些崩溃,然后他们会将这些崩溃日志(一般是ips格式的文件)反馈给开发进行分析,但是这些ips文件中的内容通常是如下 ...

随机推荐

  1. Linux用户和用户组的初步知识

    用户组相关:在Linux系统下,当创建一个如叫tom的用户,那么系统同时会创建一个叫tom的用户组linux中用户的信息都是放在/etc/passwd下的,用户的密码经过加密后放在/etc/shado ...

  2. flex布局各种情况总结分析及实例演示

    2009年,W3C提出了一种新的方案----Flex布局,可以简便.完整.响应式地实现各种页面布局.目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能. 通过笔者大量实践,发现 ...

  3. IOS中div contenteditable=true无法输入 fastclick.js在点击一个可输入的div时,ios无法正常唤起输入法键盘

    原文地址: https://blog.csdn.net/u010377383/article/details/79838562 前言 为了提升移动端click的响应速度,使用了fastclick.js ...

  4. vue2.0使用watch监听对象属性

    二话不说直接代码,找了一个百度都没找到.... var head=new Vue({ data:{ checkBoxState:{//监听设置开关勾选状态 notice:true, sound:tru ...

  5. Spark streaming技术内幕6 : Job动态生成原理与源码解析

    原创文章,转载请注明:转载自 周岳飞博客(http://www.cnblogs.com/zhouyf/)  Spark streaming 程序的运行过程是将DStream的操作转化成RDD的操作,S ...

  6. 解决lazarus 多线程报错问题

    很多人都在Windows中使用线程技术,然后同样的代码移植到Linux下一运行就出错.一开始不解其中的奥妙.既然Lazarus提供了TThread类,也没注明非要在Windows下使用.没道理在Lin ...

  7. react native 生成APK

    参考地址:React native Android 命令 打包apk 首先:尝试使用模拟器测试 这里是因为需要确认目前在电脑上的模拟器是可以正常运行的,并且,开发React native的应用程序,肯 ...

  8. 选择排序(SelectionSort)

    http://blog.csdn.net/magicharvey/article/details/10274765 算法描述 选择排序是一种不稳定排序.选择排序每次交换一对元素,它们当中至少有一个将被 ...

  9. 关于php的session.serialize_handler的问题

    前言 php的session信息是储存在文件中的 session.save_path="" 指定储存的路径 session.save_handler="" 指定 ...

  10. 洛谷P4587 [FJOI2016]神秘数(主席树)

    题面 洛谷 题解 考虑暴力,对于询问中的一段区间\([l,r]\),我们先将其中的数升序排序,假设当前可以表示出\([1,k]\)目前处理\(a_i\),假如\(a_i>k+1\),则答案就是\ ...