有时从Crashlytics收到关于objc_msgSend [__NSArrayM dealloc]崩溃的报告。

30

我最近在升级Crashlytics 3.0后收到了这个应用程序。 不确定它是来自我的代码还是其他什么东西。崩溃报告无法被追踪

Here is the crash report

Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x000000009a0dbeb8

0   libobjc.A.dylib objc_msgSend + 16 release
1   CoreFoundation  CFRelease + 524
2   CoreFoundation  -[__NSArrayM dealloc] + 152
3   libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 564
4   CoreFoundation  _CFAutoreleasePoolPop + 28
5   Foundation  -[NSAutoreleasePool release] + 148
6   UIKit   -[UIApplication _run] + 588
7   UIKit   UIApplicationMain + 1488
8   MyAppName   main.m line 32main
9  libdyld.dylib    start + 4

它是否可以持续地再现?在我看来,你似乎正在尝试访问一个已释放的NSArray实例。 - brandonscript
@remus,这种情况并不经常出现。但今天我收到了两份报告,说明这次崩溃很奇怪。之前版本的应用从未发生过这种情况。 - Kong Hantrakool
这个问题是在调试器中出现的,还是只有在生产应用商店版本中才会出现? - brandonscript
@remus 我不确定,但我在我的测试设备(开发)上从未遇到过这个错误。 - Kong Hantrakool
1
我看到了一个完全相同的崩溃。在我查看的所有日志中,这都发生在启动后不久。100%的崩溃发生在iOS 8上(尽管大多数用户都在8上)。这也是我使用更新的Fabric/Crashlytics框架发布的第一个版本。通过对整个项目进行grep,我确认没有弱NSMutableArray属性、ivars或局部变量。同样,僵尸工具也没有发现任何问题。到目前为止,我真的不知道发生了什么。 - Alex
显示剩余3条评论
5个回答

25

事实证明这是框架的错误。

以下是我从Crashlytics支持团队那里得到的信息:

如果您更新到Crashlytics SDK的3.0.10版本,问题应该就解决了。在3.0.9版本中存在一种罕见的竞争条件,我们已经在最新版本中修复了该问题。打开Fabric.app,更新框架,您就可以继续使用了 :)

Crashlytics的支持团队真是太棒了!


谢谢您。一直在寻找造成这个问题的原因,刚好开始研究 Crashlytics!如果他们接触到那些在 3.0.9 上出现此错误的开发人员并告诉他们这个情况,可能会很有用! - NeilMortonNet
2
@MRNeilM 那真的很好,或者至少在答案仪表板上有一个小警告,“嘿,如果你正在使用Crashlytics 3.0.9,那么存在崩溃问题”。我向Fabric提出了一个功能请求,希望他们能够在发布时提供发布说明的RSS订阅或电子邮件。我希望他们至少能做到这一点,这样你就会知道何时发布新的Crashlytics SDK。 - Polar Bear
@PolarBear 完全同意。我刚刚发布了我的更新,所有崩溃都停止了。 - NeilMortonNet
看起来这个问题在3.7.2版本中又出现了。 - Pavan Kunchapu
我在8.10.0版本的SDK中遇到了这个问题。 - Protocol

7

根据https://dev.twitter.com/fabric/overview/changelog,此漏洞是由Crashlytics 3.0.9引入的,该版本于2015年6月10日发布。

更新到Crashlytics 3.0.10并在周六进行了紧急更新。结果不言而喻:

周一时,无故障比率为99.9%,周二发布更新,截至6月26日星期五,无故障比率下降到98.3%,用户遇到故障的数量增加了16倍以上。 6月27日星期六,我成功地让Apple进行了加急应用程序审查,并在当天将带有Crashlytics 3.0.10的新版本发布到App Store中。 如您所见,无故障比率现在已恢复到99%,在发布几天后又回到了99.9%。

我希望这可以帮助那些因崩溃框架引入的崩溃而抓狂的人。 至少他们解决了这个问题并且新版本似乎完全解决了这个问题。


今天在仪表板上看到的就是这个。 - NeilMortonNet

6
CoreFoundation  _CFAutoreleasePoolPop + 28

自动释放池正在被清空,可能是在UI循环的末尾。这意味着池中的所有自动释放对象现在都已被释放。

CoreFoundation  -[__NSArrayM dealloc] + 152

一个可变数组被释放了。这意味着它所持有的所有项目也被释放了。
CoreFoundation  CFRelease + 524

数组中的一个元素正在被释放。

崩溃了,这个元素是无效的,它已经被释放了。

你应该检查的是数组中的元素。肯定有某个东西被过度释放了。如果你使用手动引用计数,你应该检查放入数组中的对象 - 其中一个元素已经被释放但仍然被保留在某个数组中。

在MRC下会触发类似错误的代码如下:

NSMutableArray *array = [NSMutableArray array]; //an autoreleased array
NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [[NSObject alloc] init];

[array addObject:object1]    
[array addObject:object2]    

[object1 release];
[object2 release];

//let's overrelease
[object1 release];
//when array is released, it will send a release message to object1, too

感谢您提供这么详细的答案。在 ARC 项目中可能会导致这种情况的原因是什么?我没有手动向项目中的任何对象发送 release 或 autorelease。这个崩溃出现在一个相当小的更新之后,我在提交记录中没有看到任何可疑的东西。 - Alex
@Alex 嗯,很难说。这个问题可以复现吗?可能是一个时间上的问题。 - Sulthan
完全无法重现。我自己从未见过这种崩溃。我最后一次查看时,在成千上万个会话中发生了47次。从日志中可以看出,它总是在启动后不久发生。 - Alex
@Alex 你应该检查两件具体的事情 - 1. 设备越狱可能会导致一些奇怪的崩溃 2. 人们已经开始安装iOS 9测试版。试着弄清楚问题是否与iOS 9无关。 - Sulthan
和@Alex一样。我正在使用ARC,崩溃日志来自iOS8。 - Kong Hantrakool
原来是Crashlytic/Fabric的bug,详见我的回答。 - Kong Hantrakool

2

我也曾经遇到过这种情况。只需为代码中的每个NSArray添加强引用,就再也不会出现您所见到的错误了。

最好使用以下代码:

@property(strong) NSArray *myArray.

2

看起来你释放了NSArray并且想要访问它,所以导致了崩溃。你可以在你的模型或VC中将NSArray定义为强引用。

@property(nonatomic, strong) NSArray *myArray

如果你无法猜测哪个NSArray已经被释放了,我建议你使用Instrument中的NSZombie Object调试你的应用程序,以找到确切的NSArray。

问题在于我无法重现它。 - Kong Hantrakool
我建议您在日志中(使用fabric - crashlytics)设置最后一个视图控制器的名称,并将其与崩溃报告一起发送,以查找发生错误的类。我知道找到这类崩溃的原因很难,但这是最好的找到它的方法。 - Mo Farhand
Farhad,我试过了,但这个崩溃没有发送视图控制器的名称。它说发生在main.h中。 - Kong Hantrakool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接