亮网络解锁器,解锁网络数据的无限可能 了解详情
写点什么

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:181481

评论

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

Apache ShardingSphere 如何实现分布式事务

SphereEx

Apache 数据库 ShardingSphere SphereEx

阿里云发布中国云原生数据湖应用洞察白皮书

阿里云大数据AI技术

大数据 数据湖

[Day20]-[动态规划]零钱兑换 II

方勇(gopher)

LeetCode 动态规划 数据结构算法

微信小程序开发系列(一) :开发环境搭建和微信小程序的视图设计与开发

Jerry Wang

微信小程序 微信 开发视图 微信小程序专栏 4月月更

Windows注册表内容

Sher10ck

注册表

Go 入门很简单:如何在 Go 中使用日志包

宇宙之一粟

日志 log Go 语言 4月月更

Mybatis-plus在项目中的应用

Rubble

4月日更 4月月更

融云首席科学家任杰:互联网兵无常势,但总有人正年轻

融云 RongCloud

面试突击41:notify是随机唤醒吗?

王磊

Java java面试

TASKCTL 资源树刷新、重载和重置的不同区别

TASKCTL

DevOps 分布式 敏捷开发 自动化运维 大数据运维

Cilium 原理解析:网络数据包在内核中的流转过程

火山引擎边缘云

Linux 云原生 网络

深入解析require源码,知其根,洞其源

战场小包

前端 Node 4月月更

组件容器化Statefulset与Deployment的选型与实践

移动云大数据

Deployment statefulset

制约国内企业知识管理发展的因素

小炮

知识管理 企业知识管理 企业知识管理工具

什么是域名(Domain Name ) ?

源字节1号

【高并发】如何解决可见性和有序性问题?这次彻底懂了!

冰河

并发编程 多线程 协程 异步编程 精通高并发系列

面对裁员潮,程序员如何安身立命

融云 RongCloud

Android C++系列:C++最佳实践6 constexpr与decltype

轻口味

c++ android ndk jni 4月月更

解决报错:SSL certificate problem: certificate has expired

liuzhen007

SSL证书 4月月更

架构实战营-外包学生管理系统架构文档

CityAnimal

架构实战营 #架构实战营 「架构实战营」

为什么需要可编程代理

Flomesh

负载均衡 代理 Pipy 可编程代理

Git技巧小能手

西门阿杰

git 版本控制

GAIA-IR: GraphScope 上的并行化图查询引擎

6979阿强

大数据 并行计算 图计算 GraphScope 图分析

融云互联网通信安全系列之端到端加密技术

融云 RongCloud

spring-cloud-kubernetes与SpringCloud Gateway

程序员欣宸

Java spring-cloud 4月月更

HDFS小文件分析实践

移动云大数据

hdfs 小文件

模块三-学生系统详细架构设计

ASCE

不要把公司对你的要求作为目标

张泽豪

职场 观点

学生管理系统架构文档

小虾米

架构实战营

Linux驱动框架与杂项字符设备框架介绍

DS小龙哥

4月月更

湖仓一体,Hologres加速云数据湖DLF技术原理解析

阿里云大数据AI技术

sql 大数据 分布式计算 Cloud Native MaxCompute

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