解读iPhone崩溃日志/堆栈跟踪

4
我正在使用TestFlight SDK,收到了几个完全相同的崩溃报告。然而,我很难理解这些报告,以及导致崩溃的根本原因是什么?
Exception

SIGSEGV
2 libsystem_c.dylib 0x32862e92 _sigtramp + 42
3 Foundation 0x33750d1c -[NSError dealloc] + 60...

Exception reason

SIGSEGV

Stacktrace

0 MyAppName 0x0013faba testflight_backtrace + 382
1 MyAppName 0x00140708 TFSignalHandler + 264
2 libsystem_c.dylib 0x32862e92 _sigtramp + 42
3 Foundation 0x33750d1c -[NSError dealloc] + 60
4 libobjc.A.dylib 0x39230488 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 168
5 CoreFoundation 0x31de9440 _CFAutoreleasePoolPop + 16
6 Foundation 0x33751f7a -[NSAutoreleasePool drain] + 122
7 CoreData 0x35e0a4b2 -[NSManagedObjectContext save:] + 1210
8 MyAppName 0x000b7168 MR_swapMethodsFromClass + 18076
9 CoreData 0x35e0dbc0 developerSubmittedBlockToNSManagedObjectContextPerform + 88
10 libdispatch.dylib 0x335974b6 _dispatch_client_callout + 22
11 libdispatch.dylib 0x33598dca _dispatch_main_queue_callback_4CF$VARIANT$up + 226
12 CoreFoundation 0x31e79f3a __CFRunLoopRun + 1290
13 CoreFoundation 0x31decebc CFRunLoopRunSpecific + 356
14 CoreFoundation 0x31decd48 CFRunLoopRunInMode + 104
15 GraphicsServices 0x36e092ea GSEventRunModal + 74
16 UIKit 0x320db2f8 UIApplicationMain + 1120
17 MyAppName 0x00099122 main (main.m:17)
18 MyAppName 0x000990d7 start + 39

额外信息:

  • 用户反映此崩溃在应用程序启动后1-2秒发生
  • 该应用程序使用Core Data和MagicalRecord(其中包含MR_swapMethodsFromClass方法)
  • 我无法在任何测试设备上重现此问题,当从Xcode运行时(iPhone 3GS,iPhone 4或iPhone 5)运行各种iOS版本(iOS 5.1、6.0、6.1)

编辑

仍在解决此问题......我已经能够重新创建它(但没有附加调试器)。

最奇怪的部分是 - 如果用户有旧版本的应用程序并安装更新(通过Test Flight分发),他们会收到此错误。

然而,如果他们首先删除旧应用并安装更新,则不会发生错误。


你需要对崩溃报告进行符号化处理。已经有很多现有的主题讨论如何做到这一点。苹果公司也有关于此的技术说明(或问答)。请搜索相关文档。 - rmaddy
我以为已经符号化了...?也就是说,方法名称应该显示为 MyAppName - 比如在第8行的 MR_swapMethodsFromClass 中?(我还将 .dSYM 文件上传到 TestFlight,据说可以让它自动符号化,而无需开发人员进行操作?)我是不是搞混了什么? - JRG-Developer
1
抱歉,你是正确的。我看得太快了。这似乎是一些内存管理问题。在保存托管对象上下文时,在自动释放池排空期间出现了无法释放 NSError 对象的问题。由于所有问题都始于 MagicalRecords 代码,您可能需要检查他们的支持网站。也许有一个更新版本可以使用或者这是一个已知问题。 - rmaddy
我遇到了非常相似的错误,你解决问题了吗? - Ilya K.
1
对我来说,“MR_swapMethodsFromClass + 18076”看起来非常奇怪;这个函数不可能生成18k的机器代码,也绝对不会调用“save:”。我的猜测是,要么(a)这里涉及到其他库,可能没有符号信息,该库正在调用“save:”,而“MR_swapMethodsFromClass”恰好是最接近具有符号名称的符号,要么(b)存在堆栈损坏;无论哪种情况,“MR_swapMethodsFromClass”都是一个误导。我会寻找其他可能调用“save:”和/或监听NSManagedObjectContextDidSave通知的地方。 - Jesse Rusak
@IlyaK,问题已经解决!这个问题是由于旧的NSPersistentStore和新的NSPersistentStore之间不匹配引起的。不幸的是,由于MagicalRecordinitialize方法,在DEBUG版本上设置shouldDeleteStoreOnModelMismatchYES,在生产版本上设置为NO,所以很难捕获到这个问题。如果你想在生产版本中在模型不匹配时删除模型,你必须在application:didFinishLaunchingWithOptions:方法的开头执行[MagicalRecord setShouldDeleteStoreOnModelMismatch:YES] - JRG-Developer
2个回答

17

让我们一起走过它:

0 MyAppName 0x0013faba testflight_backtrace + 382
1 MyAppName 0x00140708 TFSignalHandler + 264

那是TestFlight。这是在崩溃发生之后,所以它肯定不是原因。

2 libsystem_c.dylib 0x32862e92 _sigtramp + 42

这是我们捕获崩溃的点。“sigtramp”是信号“trampoline”的缩写。这就是说,“我捕获了一个信号(崩溃),现在我要跳到代码中的其他地方。”

3 Foundation 0x33750d1c -[NSError dealloc] + 60

啊,这很重要。我们在释放一个 NSError 时发生了崩溃。这意味着这个 NSError 被过度释放或未被保留。

4 libobjc.A.dylib 0x39230488 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 168
5 CoreFoundation 0x31de9440 _CFAutoreleasePoolPop + 16
6 Foundation 0x33751f7a -[NSAutoreleasePool drain] + 122

很遗憾...它在排空自动释放池时显现出来了。这意味着实际的错误可能离这里很远。但至少我们知道对象的类型。使用NSZombies可能有助于尝试找到特定的对象。

7 CoreData 0x35e0a4b2 -[NSManagedObjectContext save:] + 1210

自动释放池在 MOC 保存期间被清空,这表明问题可能与你的 Core Data 代码有关。至少这是你首先需要检查的地方。

需要记住的事情有:

  • 这个 bug 几乎肯定是在你的代码中。
  • 如果不是在你的代码中,那么很可能是在 Magical Record 中。
  • 不要假设它在 Core Data 中。考虑到这个堆栈,这是最不可能出错的地方。

最奇怪的部分在于——如果用户安装更新(通过 Test Flight 分发)之前使用旧版本的应用程序,则会出现此错误。

然而,如果他们首先删除旧应用程序并安装更新,则不会出现该错误。

那么问题很可能出现在你的升级代码中。最有可能是在 Core Data 迁移方面。请审核该代码区域中每个使用 NSError 的地方。消除所有编译器和分析器警告。如果可以重现错误,则尝试使用 NSZombies。


太棒了,谢谢Rob。你关于“可能在你的升级代码中”的猜测是正确的。 - JRG-Developer
tramp = 弹跳床确实很有用,但我给它加一的原因是因为它是一个非常棒的答案。 - Gordon Dove
这帮助我追踪我的应用程序问题!谢谢! - J1and1

0
你应该尝试在数据模型中添加一个模型版本。这对我很有用,我曾经遇到过类似于 Magical-Record 的问题。

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