教你如何对ios崩溃(crash)日志做符号化

一、场景

        客户端的开发流程都相似,如android,搞ios开发就要不停地发版本,随之而来的就是各种版本的崩溃日志(称为crash log)。如果不能好好地管理,那么开发人员很快就会在crash log和版本的海洋里迷失方向。解决崩溃问题是移动应用开发者最日常的工作之一。如果是开发过程中遇到的崩溃,可以根据重现步骤调试,但线上版本就无能为力了。

        国内,一般的公司是没有对ios crash符号化分析系统的,能够对ios 的crash日志做符号化做得好的公司比较少,比较好的是 “腾讯bugly”,链接:http://bugly.qq.com 。ios的日志分析,做符号化,并定位到发生崩溃的原因,对app的开发百利无一害,功德无量。

        关注问题本身,客户端开发和后台服务开发管理日志有很大的不同:

        如果是服务器报了个异常,对于java的服务,RD登上机器,看看错误的日志,看到“crash by...” 找出原因,改代码,重新编译打包部署一下就算修复了,假如是分布式的集群,服务是可以不间断的提供服务的。

        如果是客户端开发,在实际的项目开发中,崩溃问题,依赖xcode编辑器,依赖于系统记录的崩溃日志或错误堆栈,在本地开发调试阶段,是没有问题的。如果在发布的线上版本出现崩溃问题,开发者是无法即时准确的取得错误堆栈的。需要适当的时期将crash上报到服务端,由服务端处理收集分析。客户端需要重新发版才能修复旧版的crash。

      下面对ios的crash 管理做一下介绍,因为android开发是java语言,不需要做额外的处理。


二、例子

下面线上iphone的原始crash日志:

### 1.进程信息 ###
Incident Identifier: 87164E05-84A8-40F2-886D-14F90C9D3F47
CrashReporter Key:   TODO
Hardware Model:      iPhone7,2
Process:         imeituan [945]
Path:            /var/mobile/Containers/Bundle/Application/96DC918D-60C8-4C49-A51D-C0D71D0FCB4D/imeituan.app/imeituan
Identifier:      com.meituan.imeituan
Version:         895
Code Type:       ARM-64
Parent Process:  ??? [1]
 
### 2.基本信息 ###
Date/Time:       2016-02-01 16:14:24 +0000
OS Version:      iPhone OS 9.2.1 (13D15)
Report Version:  104
 
### 3.异常信息 ###
Exception Type:  SIGABRT
Exception Codes: #0 at 0x181f3c140
 
### 4.线程回溯 ###
Crashed Thread:  0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 25 beyond bounds [0 .. 24]'
 
### 5.Crash调用堆栈,需要需要将堆栈的二进制转成可读的###
Last Exception Backtrace:
0   CoreFoundation                      0x0000000182399900 0x182274000 + 1202432
1   libobjc.A.dylib                     0x0000000181a07f80 0x181a00000 + 32640
2   CoreFoundation                      0x000000018227f828 0x182274000 + 47144
3   imeituan                            0x0000000101ab593c 0x1000b8000 + 27253052
4   imeituan                            0x0000000100521a68 0x1000b8000 + 4627048
5   UIKit                               0x00000001873dd31c 0x187078000 + 3560220
6   UIKit                               0x00000001873dd484 0x187078000 + 3560580
7   UIKit                               0x00000001873cc7e8 0x187078000 + 3491816
8   UIKit                               0x00000001873e1fb0 0x187078000 + 3579824
9   UIKit                               0x000000018717708c 0x187078000 + 1044620
10  UIKit                               0x0000000187087778 0x187078000 + 63352
11  QuartzCore                          0x0000000184a96b2c 0x184a88000 + 60204
12  QuartzCore                          0x0000000184a91738 0x184a88000 + 38712
13  QuartzCore                          0x0000000184a915f8 0x184a88000 + 38392
14  QuartzCore                          0x0000000184a90c94 0x184a88000 + 35988
15  QuartzCore                          0x0000000184a909dc 0x184a88000 + 35292
16  QuartzCore                          0x0000000184a8a0cc 0x184a88000 + 8396
17  CoreFoundation                      0x0000000182350588 0x182274000 + 902536
18  CoreFoundation                      0x000000018234e32c 0x182274000 + 893740
19  CoreFoundation                      0x000000018234e75c 0x182274000 + 894812
20  CoreFoundation                      0x000000018227d680 0x182274000 + 38528
21  GraphicsServices                    0x000000018378c088 0x183780000 + 49288
22  UIKit                               0x00000001870f4d90 0x187078000 + 511376
23  imeituan                            0x0000000100112628 0x1000b8000 + 370216
24  ???                                 0x0000000181e1e8b8 0x0 + 0
 
 … 

### 6.动态库信息 ###
Binary Images:
       0x1000b8000 -        0x10275ffff +imeituan arm64  <e38d01be571931b7a4c3d9dcbf28e821> /var/mobile/Containers/Bundle/Application/96DC918D-60C8-4C49-A51D-C0D71D0FCB4D/imeituan.app/imeituan
       0x10d76c000 -        0x10d7dbfff  AGXMetalG4P arm64  <f76b11f8d06338f99ae4704aba08111c> /System/Library/Extensions/AGXMetalG4P.bundle/AGXMetalG4P
       0x182058000 -        0x18225dfff  libicucore.A.dylib arm64  <5c1540546de5350ab314c1d4c8a46d1b> /usr/lib/libicucore.A.dylib
       
 	…

       0x182274000 -        0x1825ecfff  CoreFoundation arm64  <121118a9a44d3518b99f3ebfd8806f69> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
       0x1825f0000 -   

       …
   

主要有6部分组成:

  • 1.进程信息
  • 2.基本信息
  • 3.异常信息
  • 4.线程回溯
  • 5.Crash调用堆栈(全是地址信息,需要使用符号表转成可读的)
  • 6.动态库信息(第5部分依赖的库)

 ios的符号化也主要是根据第5和第6部分进行符号化,只有把第五部分后面的二进制的地址信息映射成代码信息,才能发生crash的原因。

下面是上面的crash日志符号化后的结果:

### 1.进程信息 ###
Incident Identifier: 87164E05-84A8-40F2-886D-14F90C9D3F47
CrashReporter Key:   TODO
Hardware Model:      iPhone7,2
Process:         imeituan [945]
Path:            /var/mobile/Containers/Bundle/Application/96DC918D-60C8-4C49-A51D-C0D71D0FCB4D/imeituan.app/imeituan
Identifier:      com.meituan.imeituan
Version:         895
Code Type:       ARM-64
Parent Process:  ??? [1]

### 2.基本信息 ###
Date/Time:       2016-02-01 16:14:24 +0000
OS Version:      iPhone OS 9.2.1 (13D15)
Report Version:  104

### 3.异常信息 ###
Exception Type:  SIGABRT
Exception Codes: #0 at 0x181f3c140

### 4.线程回溯 ###Crashed Thread:  0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 25 beyond bounds [0 .. 24]'

### 5.Crash调用堆栈,需要需要将堆栈的二进制转成可读的###
Last Exception Backtrace:
0   CoreFoundation                      __exceptionPreprocess + 124
1   libobjc.A.dylib                     objc_exception_throw + 56
2   CoreFoundation                      -[__NSArrayM removeObjectAtIndex:] + 0
3   imeituan                            -[SAKFetchedResultsController objectAtIndexPath:] (SAKFetchedResultsController.m:60)
4   imeituan                            -[DEFHomePageViewController tableView:cellForRowAtIndexPath:] (DEFHomePageViewController.m:663)
5   UIKit                               -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 692
6   UIKit                               -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 80
7   UIKit                               -[UITableView _updateVisibleCellsNow:isRecursive:] + 2360
8   UIKit                               -[UITableView _performWithCachedTraitCollection:] + 104
9   UIKit                               -[UITableView layoutSubviews] + 176
10  UIKit                               -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 656
11  QuartzCore                          -[CALayer layoutSublayers] + 148
12  QuartzCore                          CA::Layer::layout_if_needed(CA::Transaction*) + 292
13  QuartzCore                          CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
14  QuartzCore                          CA::Context::commit_transaction(CA::Transaction*) + 252
15  QuartzCore                          CA::Transaction::commit() + 512
16  QuartzCore                          CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 80
17  CoreFoundation                      __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
18  CoreFoundation                      __CFRunLoopDoObservers + 372
19  CoreFoundation                      __CFRunLoopRun + 928
20  CoreFoundation                      CFRunLoopRunSpecific + 384
21  GraphicsServices                    GSEventRunModal + 180
22  UIKit                               UIApplicationMain + 204
23  imeituan                            main (main.m:34)
24  ???                                 0x0000000181e1e8b8 0x0 + 0

### 6.动态库信息 ###
Binary Images:
       0x1000b8000 -        0x10275ffff +imeituan arm64  <e38d01be571931b7a4c3d9dcbf28e821> /var/mobile/Containers/Bundle/Application/96DC918D-60C8-4C49-A51D-C0D71D0FCB4D/imeituan.app/imeituan
       0x10d76c000 -        0x10d7dbfff  AGXMetalG4P arm64  <f76b11f8d06338f99ae4704aba08111c> /System/Library/Extensions/AGXMetalG4P.bundle/AGXMetalG4P
       0x182058000 -        0x18225dfff  libicucore.A.dylib arm64  <5c1540546de5350ab314c1d4c8a46d1b> /usr/lib/libicucore.A.dylib
       
 	…

       0x182274000 -        0x1825ecfff  CoreFoundation arm64  <121118a9a44d3518b99f3ebfd8806f69> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
       0x1825f0000 -   

       …
   

那怎么将第5部分进行符号化呢?那就需要符号表了,什么是符号表呢?符号表有什么用?符号表怎么生成?符号表怎么用?

三、ios crash 日志符号化过程

(1)什么是符号表

符号表就是指在Xcode项目编译后,在编译生成的二进制文件.app的同级目录下生成的同名的.dSYM文件。.dSYM文件其实是一个目录,在子目录中包含了一个16进制的保存函数地址映射信息的中转文件,所有Debug的symbols都在这个文件中(包括文件名、函数名、行号等),所以也称之为调试符号信息文件。一般地,Xcode项目每次编译后,都会生成一个新的.dSYM文件。因此,App的每一个发布版本,都需要备份一个对应的.dSYM文件,以便后续调试定位问题。

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

 dwarfdump --uuid **.app.dSYM (**为你app)

例如:


(2)符号表有什么用

       在Xcode开发调试App时,一旦遇到崩溃问题,开发者可以直接使用Xcode的调试器定位分析。
       但如果App发布上线,开发者不可能进行调试,只能通过分析系统记录的崩溃日志来定位问题,在这份崩溃日志文件中,会指出App出错的函数内存地址,而这些函数地址是可以在.dSYM文件中找

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值