iPhone Crash stack трассировка VS Отчет о сбое - PullRequest
4 голосов
/ 01 апреля 2011

Просто провел некоторое время ... в аварии, не понимая этого. Классика:

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. Это то, что я думаю, проблема, связанная с анимацией, которая не заканчивается? похоже на это> Как отменить делегирование в UIView setAnimationDelegate: call?
  5. AFAIK, setAnimationDelegate должен сохранить делегата ... Кто-то для подтверждения?

EDIT : я не могу использовать NSZombiesEnabled, это отчет о сбое из опубликованного приложения, сбой, который мне не удалось воспроизвести в среде разработки. У меня есть только эти журналы для диагностики.

Ответы [ 4 ]

5 голосов
/ 12 декабря 2011

Всякий раз, когда я вижу objc_msgSend вверху, мое доверие к оставшемуся стеку низкое, так как ошибка, которая приводит к этому, приводит к плохим вещам в стеке.

GuardMalloc хорош для этого, так как попытка сделать что-либо с освобожденным пространством немедленно приведет к сбою приложения в отладчике.Стек будет целым.(Это делает приложение очень медленным, но это очень мощный инструмент.)

Два стека одинаковы до вызова метода UIViewAnimationState.Версия, полученная из вашего обработчика исключений, показывает искаженные имена C ++ вместо обычных имен, показанных в журнале сбоев.

(насколько я понимаю) _sigtramp - системный метод вызова вашего обработчика сигналов, и дляСигнал Батут.Вероятно, записи в стеке являются вашим кодом обработчика сигналов.

3 голосов
/ 14 июня 2011

Отвечая на мой собственный вопрос, несколько недель спустя, так как у меня не было соответствующих ответов, большинство из них являются догадками, я хотел бы иметь более точные ответы, но я думаю, что мой вопрос был неясен:

  1. Разница наступаетот источника журнала, службы sighandler vs CrashReporter, которые происходят в разное время, тогда следы стека немного отличаются.
  2. SIGBUS исходит от UIKit, но велики шансы, что это обратный вызов, инициированный моимкод, который заканчивается на освобожденном объекте.Подобные трассировки стека затрудняют отладку, когда вы не можете воспроизвести проблему, поскольку она в основном говорит вам "Я сбой где-то из-за анимации ", который, где ... Я до сих пор не понял точно.Может быть где угодно, а также может быть ошибкой Apple iOS.
  3. Первые адреса в стеке - это просто тупик , где любая трассировка стека SIGBUS заканчивается при вызове освобожденного объекта,Они отличаются в разных компиляциях (версиях), но одинаковы на любом устройстве, поэтому их нельзя символизировать.(Мне бы хотелось получить техническое объяснение этого, а не мои предположения)
  4. & 5. Думаю, я решил эту ошибку, так как стал более «агрессивным» при отмене анимации в некоторых случаях, например, при освобождении некоторых видов...

Надеюсь, это кому-нибудь поможет.

2 голосов
/ 01 апреля 2011

Вам следует попробовать NSZombie, чтобы получить информацию о том, какой объект вы выпустили. Это очень полезный инструмент, когда вы получаете EXC_BAD_ACCESS.

Чтобы активировать NSZombie, выполните следующие действия:

  1. Получить информацию об исполняемом файле.
  2. Перейти на вкладку аргументов.
  3. В разделе «Переменные для установки в среде:» добавьте:

Имя: NSZombieEnabled Значение: ДА

Затем запустите ваше приложение как обычно, и когда оно выйдет из строя, оно должно сообщить вам, какой освобожденный объект получил сообщение.

0 голосов
/ 01 апреля 2011

1. Я не уверен на 100%, но я думаю, что расхождение связано с тем, как выполняется приложение. Во втором журнале похоже, что вы запускаете приложение через XCode в режиме отладки, был отправлен сигнал sigtramp, указывающий на ошибку EXC_BAD_ACCESS.

2. Ваш код - ошибка может исходить из библиотеки UIKit, но это результат проблемы с вашим использованием.

3. Именно здесь NSZombieEnabled сделает вашу жизнь намного проще! Если вы запускаете свое приложение с установленным флагом NSZombieEnabled, XCode будет сохранять объекты «зомби» вместо освобожденных объектов. Когда объекту-зомби отправляется сообщение, процесс перехватит ошибку и сообщит вам точно, какому объекту было отправлено сообщение.

Если вы используете XCode 4, включите NSZombieEnabled, используя следующие инструкции ...

Как настроить NSZombieEnabled в Xcode 4?

Для более старых версий следуйте этим инструкциям ...

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

4. Действительно, кажется, что ваш делегат анимации был освобожден до завершения анимации.

...