iPhone崩溃的堆栈跟踪VS崩溃报告

13 浏览
0 Comments

iPhone崩溃的堆栈跟踪VS崩溃报告

刚刚花了一些时间研究了一个崩溃,但是还是没能弄清楚原因。这是一个典型的问题:

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


堆栈跟踪(catched live by an Exception Handler)

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. 据我所知,setAnimationDelegate应该保留委托...有人可以确认吗?

编辑:无法使用NSZombiesEnabled,这是一个已发布的应用程序的崩溃报告,在开发环境中我无法复现这个崩溃。我只有这些日志来诊断问题。

admin 更改状态以发布 2023年5月21日
0
0 Comments

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

  1. 差异来自于日志的来源,一个sighandler与CrashReporter服务,它们发生在不同的时间,然后堆栈跟踪略有不同。
  2. SIGBUS来自UIKit,但很有可能是由我的代码发起的回调导致了发布的对象。这些类型的堆栈跟踪在无法重现问题时很难调试,因为它基本上告诉你“我在某个地方崩溃了,因为有个动画”,是哪个动画,在哪里...我仍然无法确定。可能是任何地方,也可能是Apple iOS的一个bug。
  3. 堆栈中的第一个地址只是一个死胡同,当调用一个发布的对象时,任何SIGBUS堆栈跟踪都会在这里结束。它们在编译(版本)过程中不同,但在任何设备上都是相同的,这就是它们无法被符号化的原因。(我希望有一个技术解释,而不是我的猜测)
  4. &5.我猜我通过在某些情况下更“积极”地取消动画来解决了这个bug,比如在一些View的处理中取消动画...

希望对某人有所帮助。

0
0 Comments

每次看到 objc_msgSend 在最上面,我对剩余的堆栈的信任程度降低了,因为会出现错误,这可能会对堆栈造成不良影响。

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

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

(据我所知) _sigtramp 是系统调用你的信号处理程序的方法,它的缩写是 Signal Trampoline。那之后的堆栈条目可能是你的信号处理程序代码。

0