简单记录下我是如何根据友盟崩溃列表上的崩溃日志定位到具体哪行代码导致崩溃的 .
首先, 我用的是下图这个分析工具, 十分感谢作者的无私奉献 , 附上下载地址, 喜欢的童鞋动动小手指Star下吧
https://github.com/answer-huang/dSYMTools
打开工具后将对应版本的archive文件拖进来, 把图中对应信息按照崩溃日志里的详细信息填写
(注意一定要是对应版本的archive文件, 否则定位信息不准! 所以保留之前打包信息还是很有必要且重要的!)
崩溃日志.png
大括号里面显示调用堆栈信息, 程序调用顺序是下往上调用的, 如上图中箭头所示, 最上面那个地址也就是最后一次调用的方法, 正式它导致了崩溃, 所以在分析工具中错误信息内存地址就填这个就行了,CPU Type 和slide address 对应填即可 , 之后点击分析, 如下图所示
定位代码.png
有可能错误的地方 显示了是哪个文件的哪个方法的哪一行出错, 这个不用解释了, 直接去对应版本的代码里找到错误的地方 :
错误代码.png
定位到这行代码导致了崩溃, 检查下定位是否准确. 我们看看友盟上的错误信息
-[__NSArrayM objectAtIndex:]: index 9 beyond bounds [0 .. 2]
数组越界, 在崩溃不好重现的情况下, 我们可以很清晰的推测这行代码确实存在问题, passStr 的值可能大于数组的数量, 这时我们需要做一个安全判断,防止崩溃. 更好的方法是给数组的字典扩展一个方法, 取值时允许任何范围, 但是越界就返回空 :
- (id)objectOrNilAtIndex:(NSUInteger)index {
return index < self.count ? self[index] : nil;
}
使用分类给数组增加以上方法, 字典同理, 调用此方法替换系统方法, 代码更安全 .
有些错误日志定位的到错误信息是UmengSignalHandler时, 可以不用管
友盟的官方解释是:
UmengSignalHandler 不是错误,是捕捉crash的方法,本身不引起crash, 当crash发生时由它来捕捉。如果您不需要使用错误统计,可以通过[MobClick setCrashReportEnabled:NO];关闭。
需要注意的是, 关闭错误统计之后就不会再收到用户的崩溃日志, 所以要慎重, 在确定公司不需要统计用户崩溃信息时再关闭.
错误日志可以看出很多东西, 要学会善用错误日志 , 比如下面这个日志:
约束冲突.png
这个日志根本不需要使用分析工具定位错误代码, 直接看错误信息:
Auto Layout still required after executing -layoutSubviews. MoneyInfo's implementation of -layoutSubviews needs to call super.
如果是你负责的这部分, 那么你看到了这个信息应该能马上反应自己的约束加的是不是有问题, 毕竟自己写的代码加的约束肯定自己最清楚弱点.
如果不是你负责的这部分, 可以去看看MoneyInfo这个文件, 看看xib或者storyboard 约束是否有问题. 如果是代码加的约束, 那就只能挨个捋了.
千万不要像下面这位童鞋一样, 加完约束, 有冲突但程序没崩就不管了 . 这个习惯非常不好,一定要杜绝.
xib约束冲突.png
Xcode里也有详细的崩溃日志:
Xcode里的crash log.png
基本上能定位是哪个文件的哪个方法的哪个操作引起崩溃, 但是不能准确定位到是哪一行代码, 这里后面的+7990, +2168, +2090, +4012等这些数字我也不知道什么意思, 还希望知道的盆友告知下, 先谢谢啦~
网友评论
*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray
(null)
((
0 CoreFoundation 0x1c21ce0f <redacted> + 154
1 libobjc.A.dylib 0x1b47f077 objc_exception_throw + 38
2 CoreFoundation 0x1c1a22f7 <redacted> + 0
3 单纯测试推送 0x8a77 单纯测试推送 + 19063
4 UIKit 0x212fdee5 <redacted> + 76
5 UIKit 0x212fde73 <redacted> + 62
6 UIKit 0x212e7f97 <redacted> + 470
7 UIKit 0x212fd79b <redacted> + 634
8 UIKit 0x212fd2e7 <redacted> + 2126
9 UIKit 0x212f7ee7 <redacted> + 2662
10 UIKit 0x212c8cf5 <redacted> + 320
11 UIKit 0x21a6498d <redacted> + 2620
12 UIKit 0x21a5e5d3 <redacted> + 834
13 CoreFoundation 0x1c1d871b <redacted> + 12
14 CoreFoundation 0x1c1d8225 <redacted> + 438
15 CoreFoundation 0x1c1d64fb <redacted> + 762
16 CoreFoundation 0x1c125533 CFRunLoopRunSpecific + 486
17 CoreFoundation 0x1c125341 CFRunLoopRunInMode + 104
18 GraphicsServices 0x1d8fcbfd GSEventRunModal + 156
19 UIKit 0x21333e27 <redacted> + 574
20 UIKit 0x2132e551 UIApplicationMain + 150
21 单纯测试推送 0x9199 单纯测试推送 + 20889
22 libdyld.dylib 0x1b8ef50b <redacted> + 2
)
dSYM UUID: 05F3E63C-4D55-3CDB-9F0F-5A2C86C35C4B
CPU Type: armv7
Slide Address: 0x00004000
Binary Image: 单纯测试推送
Base Address: 0x0005a000