免费下载案例集|20+数字化领先企业人才培养实践经验 了解详情
写点什么

iOS Crash

  • 2019-09-24
  • 本文字数:6150 字

    阅读完需:约 20 分钟

iOS Crash

1 初衷

当前客户端中使用的 crash 收集工具为第三方提供,用到的第三方工具有


  • fabric

  • bugly


第三方工具在使用的过程中,存在的问题:


  • 内聚的功能过多。有的功能我们并不会用到,成为了负担

  • 定制化场景少。对于不同的 app,希望错不同的维度来查询对应的结果

  • SDK size 较大


针对上面的这些问题,打算出一套自己的 crash 工具,工具本省应该具备的功能:


  • 功能单一性

  • 健壮性

  • 定制化产出

2 发生 Crash 之后如何定位

当手机中的应用发生奔溃了之后,都会在系统日志中生成一条 crash 日志,这里为了测试,会新建一个应用,模拟 crash。比如一个数组越界的 crash


1NSMutableArray *array = [NSMutableArray array];2[array addObject:nil];
复制代码


工程创建好了之后,可以先在 xcode 中编译一下,出发这里的 demo,会发现奔溃现象,奔溃现场如下:



从奔溃的堆栈中我们可以发现如下信息:


  • reson

  • 出错堆栈

  • 函数调用的过程


当前 Debug 中看到的 crash 可读性很好,方便定位 crash 出错的位置。这是因为 XCode 默认帮我们做了很多事情,从 crash 的产生到符号化,都在无感知的状态下帮我们做好了。更有甚者,如果打开了全局的断点调试功能,在奔溃的同时还会定位到出错的代码行。这样的便利这是在 xcode IDE 环境中,现实的使用场景中,获取到的 crash,基本上是不可读的。为了模拟真实的用户场景,通过如下方式模拟:


1.archive 的方式导出当前的 release 包资源


2.载通过 itools 之类的工具安装


3.点击可以 crash 的地方,产生几条 crash 记录


正常情况下,我们启动 xcode,通过 Window -> Devices and Simulators -> 选中当前 crash 手机(这里需要 usb 连接) -> View Devices Logs。等待 xcode scaning 完成,应该就会看到 crash 文件,保险起见,最好 check 一下时间。但是也有看不到情况,例如我的 xcode 就没有执行 scaning 的操作,导致没有同步到 crash 数据。



如果遇到了同样的情况,请走下面的操作:


1.USB 连接电脑


2.打开 iTunes 同步手机到当前的电脑上


3.cd 到 ~/Library/Logs/CrashReporter/MobileDevice/** iphone


4.ls


就可以看到对应的 crash 文件了,如下



看一下同样的报错在真实环境中是什么的:


 1Incident Identifier: 056AE3FF-0053-4B5F-8C42-5CFD2F4CE9F4 2CrashReporter Key:   3c6d6b39fd3e330ce44828e97ab49661480cbb94 3Hardware Model:      iPhone10,3 4Process:             TestCrash [652] 5Path:                /private/var/containers/Bundle/Application/538B29B9-CED1-4969-913B-CB9344F70E94/TestCrash.app/TestCrash 6Identifier:          com.lianjia.TestCrash 7Version:             1 (1.0) 8Code Type:           ARM-64 (Native) 9Role:                Foreground10Parent Process:      launchd [1]11Coalition:           com.lianjia.TestCrash [682]121314Date/Time:           2018-08-10 17:43:31.2405 +080015Launch Time:         2018-08-10 17:43:27.4744 +080016OS Version:          iPhone OS 11.4.1 (15G77)17Baseband Version:    1.93.0018Report Version:      1041920Exception Type:  EXC_CRASH (SIGABRT)21Exception Codes: 0x0000000000000000, 0x000000000000000022Exception Note:  EXC_CORPSE_NOTIFY23Triggered by Thread:  02425Application Specific Information:26abort() called2728Filtered syslog:29None found3031Last Exception Backtrace:32(0x18308ad8c 0x1822445ec 0x183023750 0x182f5705c 0x1046d105c 0x18cdf964c 0x18cf1a870 0x18cdff700 0x18cf351a8 0x18ce7c9e0 0x18ce71890 0x18ce701d0 0x18d651d1c 0x18d6542c8 0x18d64d368 0x183033404 0x183032c2c 0x18303079c 0x182f50da8 0x184f36020 0x18cf70758 0x1046d1134 0x1829e1fc0)3334Thread 0 name:  Dispatch queue: com.apple.main-thread35Thread 0 Crashed:360   libsystem_kernel.dylib          0x0000000182b112e0 0x182aef000 + 140000371   libsystem_pthread.dylib         0x0000000182cb66a8 0x182caf000 + 30376382   libsystem_c.dylib               0x0000000182a7fd0c 0x182a1d000 + 404748393   libc++abi.dylib                 0x000000018221b2c8 0x18221a000 + 4808404   libc++abi.dylib                 0x000000018221b470 0x18221a000 + 5232415   libobjc.A.dylib                 0x00000001822448d4 0x18223c000 + 35028426   libc++abi.dylib                 0x000000018223537c 0x18221a000 + 111484437   libc++abi.dylib                 0x0000000182234f78 0x18221a000 + 110456448   libobjc.A.dylib                 0x00000001822447ac 0x18223c000 + 34732459   CoreFoundation                  0x0000000182f50e18 0x182f45000 + 486644610  GraphicsServices                0x0000000184f36020 0x184f2b000 + 450884711  UIKit                           0x000000018cf70758 0x18cc53000 + 32663924812  TestCrash                       0x00000001046d1134 0x1046c8000 + 371724913  libdyld.dylib                   0x00000001829e1fc0 0x1829e1000 + 40325051Thread 1:520   libsystem_pthread.dylib         0x0000000182cafb04 0x182caf000 + 28205354Thread 2:550   libsystem_pthread.dylib         0x0000000182cafb04 0x182caf000 + 28205657Thread 3:580   libsystem_pthread.dylib         0x0000000182cafb04 0x182caf000 + 28205960Thread 4:610   libsystem_kernel.dylib          0x0000000182b11d78 0x182aef000 + 142712621   libsystem_pthread.dylib         0x0000000182cb00a0 0x182caf000 + 4256632   libsystem_pthread.dylib         0x0000000182cafb08 0x182caf000 + 28246465Thread 5 name:  com.apple.uikit.eventfetch-thread66Thread 5:670   libsystem_kernel.dylib          0x0000000182aefde8 0x182aef000 + 3560681   libsystem_kernel.dylib          0x0000000182aefc60 0x182aef000 + 3168692   CoreFoundation                  0x0000000183032e40 0x182f45000 + 974400703   CoreFoundation                  0x0000000183030908 0x182f45000 + 964872714   CoreFoundation                  0x0000000182f50da8 0x182f45000 + 48552725   Foundation                      0x00000001839c5674 0x1839bd000 + 34420736   Foundation                      0x00000001839c551c 0x1839bd000 + 34076747   UIKit                           0x000000018cc55768 0x18cc53000 + 10088758   Foundation                      0x0000000183ad5efc 0x1839bd000 + 1150716769   libsystem_pthread.dylib         0x0000000182cb1220 0x182caf000 + 87367710  libsystem_pthread.dylib         0x0000000182cb1110 0x182caf000 + 84647811  libsystem_pthread.dylib         0x0000000182cafb10 0x182caf000 + 28327980Thread 6:810   libsystem_pthread.dylib         0x0000000182cafb04 0x182caf000 + 28208283Thread 0 crashed with ARM Thread State (64-bit):84    x0: 0x0000000000000000   x1: 0x0000000000000000   x2: 0x0000000000000000   x3: 0x00000001cc0eedb785    x4: 0x000000018223aabd   x5: 0x000000016b7373f0   x6: 0x000000000000006e   x7: 0x000000000000030b86    x8: 0x0000000008000000   x9: 0x0000000004000000  x10: 0x0000000182cb2110  x11: 0x000000000000000387   x12: 0xffffffffffffffff  x13: 0x0000000000000001  x14: 0x0000000000000000  x15: 0x000000000000001088   x16: 0x0000000000000148  x17: 0x0000000000000300  x18: 0x0000000000000000  x19: 0x000000000000000689   x20: 0x00000001b55dbb40  x21: 0x000000016b7373f0  x22: 0x0000000000000303  x23: 0x00000001b55dbc2090   x24: 0x0000000000000001  x25: 0x00000001c00199f0  x26: 0x0000000000000000  x27: 0x000000000000000191   x28: 0x000000016b737b38   fp: 0x000000016b737350   lr: 0x0000000182cb66a892    sp: 0x000000016b737320   pc: 0x0000000182b112e0 cpsr: 0x000000009394Binary Images:950x1046c8000 - 0x1046d3fff TestCrash arm64  <1033c07aba8b3895bd20eb85e761bb49> /var/containers/Bundle/Application/538B29B9-CED1-4969-913B-CB9344F70E94/TestCrash.app/TestCrash96...970x1ab910000 - 0x1ab940fff libclosured.dylib arm64  <e61ffac51cae3e1fb9eb6a6e2801777b> /usr/lib/closure/libclosured.dylib9899EOF
复制代码


这里是未符号化的 crash 文件。符号化 crash 文件还需要对应的符号文件,这个符号文件可以在之前的 archive 中找到,路径为:Xcode -> Window -> Organizer -> Archive -> 选中 App -> 选中其中的最顶部的 archive -> show in finder -> 显示包内容 -> dsYMs 文件下 -> **.app.dSYM。

3 手动符号化文件

为了之后的操作方便,可以将 crash 文件和 dYSM 文件放在同一个文件夹下。首先需要确定当前的 crash 文件和 dSYM 文件是否是一一对应的,校验的规则为比对 uuid 是否相同(这里的 UUID 是 build 级别的,每次 build 产生的 UUID 都有可能不相同),使用如下命令获取 crash uuid


1grep "appName arm" *.crash2结果:3TestCrash-2018-08-10-174331.crash:0x1046c8000 - 0x1046d3fff TestCrash arm64  4<1033c07aba8b3895bd20eb85e761bb49> /var/containers/Bundle/Application/538B29B9-CED1-4969-913B-CB9344F70E94/TestCrash.app/TestCrash
复制代码


使用如下命令查看 dYSM 文件的 uuid


1dwarfdump --uuid TestCrash.app.dSYM/Contents/Resources/DWARF/TestCrash2结果:UUID: 1033C07A-BA8B-3895-BD20-EB85E761BB49 (arm64) TestCrash.app.dSYM/Contents/Resources/DWARF/TestCrash
复制代码


确定了上面的事情之后,使用符号化工具 symbolicatecrash,使用之前需要先导出这个工具,使用如下命令:


1export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer


运行了之后看一下本地文件下有没有 symbolicatecrash,如果不存在,可以使用如下命令查看 symbolicatecrash 所在位置:


1find /Applications/Xcode.app/ -name symbolicatecrash2结果可能是多个3/Applications/Xcode.app//Contents/Developer/Platforms/WatchSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash4/Applications/Xcode.app//Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash5/Applications/Xcode.app//Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash6/Applications/Xcode.app//Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash7选择SharedFramework中的文件 copy 到本地8cp /Applications/Xcode.app//Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash ./
复制代码


当前文件已经存在直接运行


1./symbolicatecrash TestCrash-2018-08-10-174331.crash TestCrash.app.dSYM > a.log
复制代码


符号化之后的文件如下


 1... 2 3Last Exception Backtrace: 40   CoreFoundation                  0x18308ad8c __exceptionPreprocess + 228 51   libobjc.A.dylib                 0x1822445ec objc_exception_throw + 55 62   CoreFoundation                  0x183023750 _CFThrowFormattedException + 111 73   CoreFoundation                  0x182f5705c -[__NSArrayM insertObject:atIndex:] + 1411 84   TestCrash                       0x1046d105c -[ViewController function9] + 36956 (ViewController.m:88) 95   UIKit                           0x18cdf964c -[UIApplication sendAction:to:from:forEvent:] + 95106   UIKit                           0x18cf1a870 -[UIControl sendAction:to:forEvent:] + 79117   UIKit                           0x18cdff700 -[UIControl _sendActionsForEvents:withEvent:] + 439128   UIKit                           0x18cf351a8 -[UIControl touchesEnded:withEvent:] + 571139   UIKit                           0x18ce7c9e0 -[UIWindow _sendTouchesForEvent:] + 24271410  UIKit                           0x18ce71890 -[UIWindow sendEvent:] + 31591511  UIKit                           0x18ce701d0 -[UIApplication sendEvent:] + 3391612  UIKit                           0x18d651d1c __dispatchPreprocessedEventFromEventQueue + 23391713  UIKit                           0x18d6542c8 __handleEventQueueInternal + 47431814  UIKit                           0x18d64d368 __handleHIDEventFetcherDrain + 1511915  CoreFoundation                  0x183033404 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 232016  CoreFoundation                  0x183032c2c __CFRunLoopDoSources0 + 2752117  CoreFoundation                  0x18303079c __CFRunLoopRun + 12032218  CoreFoundation                  0x182f50da8 CFRunLoopRunSpecific + 5512319  GraphicsServices                0x184f36020 GSEventRunModal + 992420  UIKit                           0x18cf70758 UIApplicationMain + 2352521  TestCrash                       0x1046d1134 main + 37172 (main.m:14)2622  libdyld.dylib                   0x1829e1fc0 start + 32728...
复制代码

4 借助工具完成符号化

从上面手动解析的工程中,我们可以看到,需要的数据和工具有


  • dSYM 文件

  • symbolicatecrash 工具


并且这两个工具都在 xcode 中,前提条件是这个 ipa 包是通过你的 xcode archive 出去的,当前的机器上保留了 dSYM 文件。之后只需要将 crash 文件拖到 xcode crash 中就会自动解析了。效果如下:


5 发 Xcode 统计的 Crash

app 上传到 APP store 之后,使用过程中产生的 crash,同时当前的设备打开了日志分析的功能,crash 日志就会被 Apple 统计到。通过步骤 Xcode -> Window -> Organizer -> 选中 Crash -> 选中对应的 app 可以看到对应的 crash,符号化的过程,可以在本地,也可以在 apple 服务端,取决于,上传 app 二进制包的时候,有没有将符号文件一并上传。效果如下:



6 需要注意的点

在 archive 的时候,不要选 bitCode,否则安装的二进制造成的 crash 无法符号化。原因使用 bitCode 上传给 apple,bitCode 只是一个中间码,需要根据不同的架构来决定最终生成的代码是什么?所以,如果使用 bitCode 上传的话,需要向 apple 下载 dSYM 文件。如下是使用 bitcode 发布时的流程图:



作者介绍:


汪汉东,贝壳前端开发工程师,目前负责租赁事业部前端研发工作。


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


https://mp.weixin.qq.com/s/2FcSZdq7GS57UVBpaxVBTQ


2019-09-24 10:181588

评论

发布
暂无评论
发现更多内容

消息中间件

Damon

7月月更

如何在Docker部署安装ETL调度运维工具TASKCTL

敏捷调度TASKCTL

DevOps 大数据运维 Kafka ETL TASKCTL Docker 镜像

服务器运维需要24小时在线吗?需要周末加班吗?

行云管家

服务器 IT运维

短视频直播系统源码

开源直播系统源码

短视频源码 直播系统源码 短视频直播系统

李宏毅《机器学习》丨3. Gradient Descent(梯度下降)

AXYZdong

机器学习 7月月更

不是我说,不掌握这些坑,你敢用BigDecimal吗?

程序员小毕

Java 程序员 面试 后端 BigDecimal

如何选择合适的体育场馆用LED显示屏

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

发现增长新动力,企业到底需要一朵什么样的云?

ToB行业头条

京东云联合Forrester咨询发布混合云报告 云原生成为驱动产业发展新引擎

京东科技开发者

云原生 数字化 科技 混合云 多云

数据仓库开发 SQL 使用技巧总结

C++后台开发

MySQL 数据库 sql 中间件 后端开发

Python图像处理丨三种实现图像形态学转化运算模式

华为云开发者联盟

Python 人工智能 AI 图像形态学

实操演示:如何用 ONES 制定 Scrum 迭代计划?

万事ONES

医院怎么实现高效低成本运维?有什么软件可以满足吗?

行云管家

运维 IT运维 医院运维

ABAP-EXCEL上传下载

桥下本有油菜花

abap ABAPexcel

Ampere Altra Max 提供可持续的高分辨率 H.265 编码

亚马逊云科技 (Amazon Web Services)

编码 Tech 专栏

直播预告 | 多云时代如何建设企业云管理平台?

BoCloud博云

cmp 云管理平台 云管理

一文了解 Nebula Graph 上的 Spark 项目

NebulaGraph

spark 图数据库 知识图谱 NebulaGraph

LabView中禁用模块(属性节点)

一碗黄豆酱

IT小白也能轻松get日志服务---使用Nginx模式采集日志

云端explorer

nginx 运维 日志服务

React原理学习路线

郭明

汇聚开发者智慧 夯实数据库产业根基

科技热闻

小李:“有没有特别简单的Python解密rsa的案例?”“还真有”

梦想橡皮擦

Python 爬虫 7月月更

LabView实验——温度检测系统(实验学习版)

一碗黄豆酱

云图说丨数字资产链:您的数字资产产权保护神

华为云开发者联盟

区块链 云计算 开发 开发工具

如何做好安全开发?

华为云开发者联盟

云计算 开源 安全 开发

AIOps 还是 APM,企业用户应如何作出选择?

云智慧AIOps社区

APM 智能运维AIOps

LabView---信号发生器

一碗黄豆酱

可以 DIY 装修的商城系统,你也能拥有!

CRMEB

百度APP Android包体积优化实践(一)总览

百度Geek说

Java 安卓

低代码软件开发平台怎么选?

优秀

低代码开发 低代码平台

2022年中国娱乐直播市场年度综合分析

易观分析

直播市场

iOS Crash_文化 & 方法_汪汉东_InfoQ精选文章