转自:http://www.cocoachina.com/industry/20140514/8418.html

转自wufawei的博客

当你的应用提交到App Store或者各个渠道之后,请问你多久会拿到crash文件?你如何分析crash文件的呢?

 
上传crash文件
你的应用应当有模块能够在应用程序crash的时候上传crash信息。 要么通过用户反馈拿到crash文件,要么借助自己或第3方的crash上传模块拿到crash文件。
 
今天要分析的场景是你拿到用户的.crash文件之后,如何符合化crash文件(Symbolicating crash logs)的3种方法。帮助尽快找到crash原因。
 
crash文件例子
crash文件的部分内容:
 Last Exception Backtrace:

0 CoreFoundation 0x30acaf46 exceptionPreprocess + 126
1 libobjc.A.dylib 0x3af0b6aa objc_exception_throw + 34
2 CoreFoundation 0x30a0152e -[__NSArrayM objectAtIndex:] + 226
3 appName 0x000f462a 0x4000 + 984618
4 appName 0x00352aee 0x4000 + 3468014
18 appName 0x00009404 0x4000 + 21508
 
大家一眼就能看到:
 2 CoreFoundation 0x30a0152e -[__NSArrayM objectAtIndex:] + 226
 
这一行有问题。
 
但是,第3行和第4行的:
 3 appName 0x000f462a 0x4000 + 984618

4 appName 0x00352aee 0x4000 + 3468014
 
并没有指出到底是app的那个模块导致的问题,如何排查呢?
 
有如下3种方法
 
方法1 使用XCode
这种方法可能是最容易的方法了。
 
需要使用Xcode符号化 crash log,你需要下面所列的3个文件:
1. crash报告(.crash文件)
2. 符号文件 (.dsymb文件)
3. 应用程序文件 (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
有时候Xcode不能够很好的符号化crash文件。我们这里介绍如何通过symbolicatecrash来手动符号化crash log。
 
在处理之前,请依然将“.app“, “.dSYM”和 ".crash"文件放到同一个目录下。现在打开终端(Terminal)然后输入如下的命令:
  1. export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
 
然后输入命令:
  1. /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash appName.app > appName.log
 
现在,符号化的crash log就保存在appName.log中了。
 
方法3 使用命令行工具atos
如果你有多个“.ipa”文件,多个".dSYMB"文件,你并不太确定到底“dSYMB”文件对应哪个".ipa"文件,那么,这个方法就非常适合你。
 
特别当你的应用发布到多个渠道的时候,你需要对不同渠道的crash文件,写一个自动化的分析脚本的时候,这个方法就极其有用。
 
这里先介绍一个概念:UUID
 
什么是UUID
每一个可执行程序都有一个build UUID来唯一标识。Crash日志包含发生crash的这个应用(app)的 build UUID以及crash发生的时候,应用加载的所有库文件的[build UUID]。
 
那如何知道crash文件的UUID呢?
 
可以用:
  1. grep "appName armv" *crash
 
或者
  1. grep --after-context=2 "Binary Images:" *crash
 
可以得到类似如下的结果:
  1. appName.crash-0x4000 - 0x9e7fff appName armv7 <8bdeaf1a0b233ac199728c2a0ebb4165> /var/mobile/Applications/A0F8AB29-35D1-4E6E-84E2-954DE7D21CA1/appName.crash.app/appName
 
(请注意这里的0x4000,是模块的加载地址,后面用atos的时候会用到)
 
如何找到app的UUID
可以使用命令:
  1. xcrun dwarfdump -–uuid <AppName.app/ExecutableName>
 
比如:
  1. xcrun dwarfdump --uuid appName.app/appName
 
结果如下:
  1. UUID: 8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165 (armv7) appName.app/appName
  2. UUID: 5EA16BAC-BB52-3519-B218-342455A52E11 (armv7s) appName.app/appName
 
这个app有2个UUID,表明它是一个fat binnary。
 
它能利用最新硬件的特性,又能兼容老版本的设备。
 
对比上面crash文件和app文件的UUID,发现它们是匹配的:
  1. 8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165
 
用atos命令来符号化某个特定模块加载地址
命令是:
  1. atos [-o AppName.app/AppName] [-l loadAddress] [-arch architecture]
 
亲测,下面3种都可以:
  1. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7
  2. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -arch armv7
  3. xcrun atos -o appName.app/appName -arch armv7
(注:这3行选任意一行执行都可以达到目的,其中0x4000是模块的加载地址,从上面的章节可以找到如何得到这个地址。)
 
文章开头提到crash文件中有如下两行,
  1. * 3 appName 0x000f462a 0x4000 + 984618
  2. * 4 appName **0x00352aee** 0x4000 + 3468014
 
在执行了上面的:
  1. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7
 
之后,输入如下地址:
  1. 0x00352aee
 
(crash文件中的第4行:4 appName **0x00352aee** 0x4000 + 3468014)
 
可以得到结果:
  1. -[UIScrollView(UITouch) touchesEnded:withEvent:] (in appName) (UIScrollView+UITouch.h:26)
 
这样就找到了应用种到底是哪个模块导致的crash问题。
 
总结
本文分析了拿到用户的.crash文件之后,如何符合化crash文件的3种方法,分别有其适用场景,方法3适用于自动化crash文件的分析。
 
参见:

分析iOS Crash文件:符号化iOS Crash文件的3种方法的更多相关文章

  1. 从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法

    原文:从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法 主程序 为 Main_Test.exe 被加载的DLL 为 Load_Test.dll  此DLL 中 有一个 文件夹Re ...

  2. 使用.Htaccess文件实现301重定向常用的七种方法

    使用.Htaccess文件实现301重定向常用的七种方法   301重定向对广大站长来说并不陌生,从网站建设到目录优化,避免不了对网站目录进行更改,在这种情况下用户的收藏夹里面和搜索引擎里面可能保存的 ...

  3. Mac OX 隐藏文件夹,文件,应用,磁盘的2种方法 hide finder folder, file, application, volume in 2 ways

    经常需要主目录下隐藏一些文件夹之类的, 第一想到的当然就是:在要隐藏的文件夹前面加『.』(leading dot),这个用法当然可以的了 用习惯了Linux/GNU系统的,基本习惯使用这种办法 但是, ...

  4. 【技术宅3】截取文件和url扩展名的N种方法

    //截取文件扩展名的N种方法   //第1种 //strrchr() 函数查找字符在指定字符串中最后一次出现的位置,如果成功,则返回其后面的字符串 //返回带有点的扩展名 function get_e ...

  5. 将ipa文件安装到测试设备上的几种方法

    Installing Your App on Test Devices Using Xcode You can install iOS App files on devices using Xcode ...

  6. iOS 更改状态栏、导航栏颜色的几种方法

    ios上状态栏 就是指的最上面的20像素高的部分状态栏分前后两部分,要分清这两个概念,后面会用到: 前景部分:就是指的显示电池.时间等部分:背景部分:就是显示黑色或者图片的背景部分: (一)设置sta ...

  7. mysql 从 frm 文件恢复 table 表结构的3种方法

    mysql 正常运行的时候,查看 table 的结构并不是困难的事. 但是有时 mysql 发生故障,这种方法便不再可行. 当遇到故障,通常使用新的 mysql 实例来恢复当前的数据. 建表是非常重要 ...

  8. iOS/Android网络消息推送的实现两种方法

    移动时代,用户为王,而每个APP拥有的活跃用户量(Active Users),决定了其价值. 消息推送成为了不可或缺的活跃唤起工具. 目前消息推送有如下两种途径: 1.iOS传统方式: 通过Apple ...

  9. C# 截取带路径的文件名字,扩展名,等等 的几种方法

    C#对磁盘IO操作的时候,经常会用到这些,路径,文件,文件名字,文件扩展名. 之前,经常用切割字符串来实现, 可是经常会弄错. 尤其是启始位置,多少个字节,经常弄晕. 下面这种方法貌似比较简便: st ...

  10. iOS边练边学--介绍布局的三种方法

    使用代码实现Autolayout的方法1- 创建约束 +(id)constraintWithItem:(id)view1attribute:(NSLayoutAttribute)attr1relate ...

随机推荐

  1. PostgreSQL时间格式及相关函数实践

    在创建表的时候,有客户需要将时间转为字符串,而且要求了具体的格式,如:20181115101010001.方便记录数据的更新时间,貌似是给Mysql使用,当时就很蛋疼,时间格式存储子啊数据库中就是va ...

  2. SpringMVC札集(09)——拦截器

    自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onL ...

  3. azure 架构选择

    在azure中主要有以下3种不同的托管环境. 平台即服务(PaaS)提供了可管理的托管环境,可以直接部署应用而不需要关心背后的虚拟机和网络资源.例如,当需要托管一个应用时,只需要指定实例的个数,azu ...

  4. .NET 方法回调

    使用 AsyncCallback 委托在一个单独的线程中处理异步操作的结果. AsyncCallback 委托表示在异步操作完成时调用的回调方法. 回调方法采用 IAsyncResult 参数,该参数 ...

  5. python爬虫入门(1)-urllib模块

    作用:用于读取来自网上(服务器上)的数据   基本方法:urllib.request.urlopen(url,data=None,[]timeout]*,cafile=None,cadefault=F ...

  6. ptr_fun

    ptr_fun 分类: C/C++2012-05-05 20:21 593人阅读 评论(0) 收藏 举报 functionclassfunobjectreturningtypes   目录(?)[-] ...

  7. Mysql按照字段值做分组行转列查询

    今天做个后台服务,有个需求是批量生成一批表的数据,如果用BulkInsert会提升很大一截提交效率,但是如果用循环构造提交的Datable,则算法开销太高,所以用这种查询批量查出符合格式的DataTa ...

  8. 每天一个linux命令(性能、优化):【转载】free命令

    free命令可以显示Linux系统中空闲的.已用的物理内存及swap内存,及被内核使用的buffer.在Linux系统监控的工具中,free命令是最经常使用的命令之一. 1.命令格式: free [参 ...

  9. BZOJ4820 Sdoi2017 硬币游戏 【概率期望】【高斯消元】【KMP】*

    BZOJ4820 Sdoi2017 硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实 ...

  10. (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序

    每次使用 Visual Studio 的模板创建一个 UWP 程序,我们会在项目中发现大量的项目文件.配置.应用启动流程代码和界面代码.然而这些文件在 UWP 程序中到底是如何工作起来的? 我从零开始 ...