【问题标题】:iPhone Crash stack trace VS Crash reportiPhone 崩溃堆栈跟踪 VS 崩溃报告
【发布时间】:2011-07-27 12:35:56
【问题描述】:

只是花了一些时间...在崩溃上,但没有理解它。很经典:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000010

这导致我出现内存问题,解决无效地址0x10

困扰我的是我有崩溃报告和堆栈跟踪,它们不同:


用户发送的崩溃报告(符号化成功,发生):

Thread 0 Crashed:
0   libobjc.A.dylib                 0x000027d8 objc_msgSend + 16
1   UIKit                           0x0005e9d2 -[UIViewAnimationState animationDidStop:finished:] + 54
2   QuartzCore                      0x0002d8c2 run_animation_callbacks(double, void*) + 286
3   QuartzCore                      0x0002d764 CA::timer_callback(__CFRunLoopTimer*, void*) + 116
4   CoreFoundation                  0x000567f4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 8
5   CoreFoundation                  0x000562a6 __CFRunLoopDoTimer + 854
6   CoreFoundation                  0x0002779e __CFRunLoopRun + 1082
7   CoreFoundation                  0x00027270 CFRunLoopRunSpecific + 224
8   CoreFoundation                  0x00027178 CFRunLoopRunInMode + 52
9   GraphicsServices                0x000045ec GSEventRunModal + 108
10  GraphicsServices                0x00004698 GSEventRun + 56
11  UIKit                           0x0000411c -[UIApplication _run] + 396
12  UIKit                           0x00002128 UIApplicationMain + 664
13  MyApp                           0x00003158 main (main.m:13)
14  MyApp                           0x00003120 0x1000 + 8480

崩溃堆栈跟踪(由异常处理程序实时捕获)

0   MyApp                               0x000d79c3 0x0 + 883139
1   MyApp                               0x000d790b 0x0 + 882955
2   libSystem.B.dylib                   0x302765d3 _sigtramp + 42
3   UIKit                               0x31eab9d9 -[UIViewAnimationState animationDidStop:finished:] + 60
4   QuartzCore                          0x33a178c9 _ZL23run_animation_callbacksdPv + 292
5   QuartzCore                          0x33a1776b _ZN2CAL14timer_callbackEP16__CFRunLoopTimerPv + 122
6   CoreFoundation                      0x3084e7fb __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
7   CoreFoundation                      0x3084e2ad __CFRunLoopDoTimer + 860
8   CoreFoundation                      0x3081f7a5 __CFRunLoopRun + 1088
9   CoreFoundation                      0x3081f277 CFRunLoopRunSpecific + 230
10  CoreFoundation                      0x3081f17f CFRunLoopRunInMode + 58
11  GraphicsServices                    0x31e445f3 GSEventRunModal + 114
12  GraphicsServices                    0x31e4469f GSEventRun + 62
13  UIKit                               0x31e51123 -[UIApplication _run] + 402
14  UIKit                               0x31e4f12f UIApplicationMain + 670
15  MyApp                               0x0000315f 0x0 + 12639
16  MyApp                               0x00003128 0x0 + 12584

两者不同,堆栈跟踪指向我的代码中的崩溃,但在地址处我既不能符号化也不能识别。我认为崩溃报告表明消息已发送到已发布的实例...可能与使用有关:

+ (void)setAnimationDelegate:(id)delegate
+ (void)setAnimationDidStopSelector:(SEL)selector

所以这里(终于!)是我的问题:

  1. 什么解释了日志之间的差异? (libobjc.A vs libSystem.B ??)
  2. SIGBUS 是来自我的代码还是来自 UIKit?
  3. 如何破译堆栈跟踪上位地址(0x000d79??,atos 无法解析)
  4. 我认为这是与动画未能结束有关的问题吗?类似的>How to unset delegate on UIView setAnimationDelegate: call?
  5. AFAIK,setAnimationDelegate 应该保留委托...有人确认吗?

编辑:我不能使用NSZombiesEnabled,这是来自已发布应用程序的崩溃报告,我无法在开发环境中重现崩溃。我只有这些日志要诊断。

【问题讨论】:

    标签: iphone crash stack-trace report


    【解决方案1】:

    每当我在顶部看到 objc_msgSend 时,我对剩余堆栈的信任度很低,因为产生这种情况的错误往往会对堆栈造成不良影响。

    GuardMalloc 对此很有用,因为尝试对已释放空间进行任何操作都会使应用程序立即在调试器中崩溃。堆栈将完好无损。 (这使得应用程序很慢,但它是一个非常强大的工具。)

    在 UIViewAnimationState 方法调用之前,这两个堆栈是相同的。来自您的异常处理程序的版本显示的是 C++ 错误名称,而不是崩溃日志中显示的常规名称。

    (据我了解)_sigtramp 是系统调用信号处理程序的方法,是 Signal Trampoline 的缩写。除此之外的堆栈条目可能是您的信号处理程序代码。

    【讨论】:

    • 感谢您的回复,其中包含一些有价值的信息 :) 关于 sigtramp 之外的堆栈条目,当您向已释放的实例发送消息时,这些是“默认”地址。正如其他回复所述,GuardMalloc 是不可能的,崩溃只发生在我无法访问的用户设备上。谢谢你的时间:)
    • 同意,您无法在用户设备上运行 GuardMalloc。但是,您可以使用 GuardMalloc 在模拟器中运行该确切代码,如果存在导致指针悬空的缺陷,您会在代码崩溃时找到它。
    【解决方案2】:

    几周后回答我自己的问题,因为我没有相关答案,大部分都是猜测,我希望我有更准确的答案,但我想我的问题不清楚:

    1. 不同之处在于日志的来源,一个 sighandler 与 CrashReporter 服务,它们发生在不同的时间,然后堆栈跟踪略有不同。
    2. SIGBUS 来自 UIKit,但很有可能发生在从我的代码发起的回调上,该回调以已发布的对象结束。当您无法重现问题时,这类堆栈跟踪很难调试,因为它基本上会告诉您“由于动画,我在某处崩溃了>",哪一个,在哪里……我还是没弄清楚。可能在任何地方,也可能是 Apple iOS 错误。
    3. 堆栈中的第一个地址只是一个死胡同,当调用释放的对象时,任何 SIGBUS 堆栈跟踪都会结束。它们在编译(版本)中有所不同,但在任何设备上都是相同的,这就是它们不能被符号化的原因。 (我希望对此有一个技术解释,而不是我的猜测)
    4. & 5. 我想我解决了这个错误,因为在某些情况下取消动画时更加“激进”,例如在取消分配某些视图时...

    希望对某人有所帮助。

    【讨论】:

      【解决方案3】:

      您应该尝试 NSZombie,以获取有关您已发布的对象的信息。当您获得 EXC_BAD_ACCESS 时,这是一个非常有用的工具。

      要激活 NSZombie,请执行以下操作:

      1. 获取可执行文件的信息。
      2. 转到参数选项卡。
      3. 在“要在环境中设置的变量:”部分添加:

      名称:NSZombieEnabled 值:是

      然后像往常一样运行你的应用程序,当它崩溃时它应该告诉你哪个被释放的对象收到了消息。

      【讨论】:

      • 谢谢,但我知道 NSZombies...我只是无法重现该错误并拥有日志。
      • @Erik 我更喜欢像这样寻找僵尸:stackoverflow.com/questions/2190227/…
      • @Besi 这是 Xcode 3 的旧答案。预计会过时。不管怎样,谢谢你的分享。
      【解决方案4】:

      1. 我不能 100% 确定,但我认为差异是由于应用程序的运行方式造成的。在第二个日志中,您似乎在调试模式下通过 XCode 运行应用程序,已发送 sigtramp 信号以指示 EXC_BAD_ACCESS 错误。

      2.您的代码 - 错误可能来自 UIKit 库,但它是您的使用问题的结果。

      3. 这就是 NSZombieEnabled 将使您的生活更轻松的地方!如果您使用设置了 NSZombieEnabled 标志运行您的应用程序,XCode 将保留“僵尸”对象来代替已释放的对象。当僵尸对象发送消息时,该进程将捕获错误并让您确切知道发送消息的对象。

      如果您使用的是 XCode 4,请按照以下说明启用 NSZombieEnabled...

      How do I set up NSZombieEnabled in Xcode 4?

      对于旧版本,请遵循这些说明...

      http://www.cocoadev.com/index.pl?NSZombieEnabled

      4. 确实,您的动画委托似乎在动画完成之前已被释放。

      【讨论】:

      • 相同的评论,我无法重现该错误,只有日志可以诊断。编辑问题以澄清这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多