#iphone #ios #crash
#iPhone #iOS #сбой
Вопрос:
Мое приложение недавно начало показывать странные сбои, которые я не могу отследить до источника. Любая помощь в том, что искать, была бы полезна 🙂
В журналах сбоев с устройства (iPad iOS 5) в начале отображаются следующие данные:
Date/Time: 2011-11-08 19:07:21.044 0100
OS Version: iPhone OS 5.0 (9A334)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x406cad3d
Crashed Thread: 9
Завершившийся сбоем поток 9 является AQClient
потоком, и его трассировка стека выглядит следующим образом:
Thread 9 name: AQClient
Thread 9 Crashed:
0 libobjc.A.dylib 0x30107fbc objc_msgSend 16
1 AVFoundation 0x3420cdc8 _ZL27AudioPlayerAQOutputCallbackPvP16OpaqueAudioQueueP16AudioQueueBuffer 28
2 AudioToolbox 0x32a409fe ClientMessageHandler::OutputBufferComplete(unsigned int) 98
3 AudioToolbox 0x32a425d6 AQClientCallbackMessageReader::DispatchCallbacks(unsigned char*, unsigned int, void*, unsigned int) 198
4 AudioToolbox 0x32a408dc AQCallbackReceiver_CallbackNotificationsAvailable 364
5 AudioToolbox 0x329ee4b6 _XCallbackNotificationsAvailable 54
6 AudioToolbox 0x329e436c mshMIGPerform 368
7 CoreFoundation 0x34fa454c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ 32
8 CoreFoundation 0x34fa44ee __CFRunLoopDoSource1 134
9 CoreFoundation 0x34fa333c __CFRunLoopRun 1364
10 CoreFoundation 0x34f264d6 CFRunLoopRunSpecific 294
11 CoreFoundation 0x34f2639e CFRunLoopRunInMode 98
12 AudioToolbox 0x32a3d29c GenericRunLoopThread::Entry(void*) 116
13 AudioToolbox 0x329c5aac CAPThread::Entry(CAPThread*) 208
14 libsystem_c.dylib 0x35756c16 _pthread_start 314
15 libsystem_c.dylib 0x35756ad0 thread_start 0
Похоже, это связано с активностью AVAudioPlayer или MPMoviePlayer. В приложении у меня воспроизводится фильм (.m4v из пакета приложения), затем, когда он завершен, просмотр переворачивается в сторону без фильма, и начинается воспроизведение звука.
В случае сбоев я слышу, что один и тот же звук воспроизводится дважды, даже если это не предназначено. Затем по завершении аудио (когда AVAudioPlayer должен быть освобожден) приложение завершает работу.
Я добавил некоторые NSLog
в приложение, чтобы отследить, что здесь происходит. Консоль в критический момент показала мне такую вещь:
Nov 8 19:17:19 unknown XXX[1753] <Warning>: Finished movie
Nov 8 19:17:19 unknown XXX[1753] <Warning>: Finished movie
Nov 8 19:17:20 unknown XXX[1753] <Warning>: flipping
Nov 8 19:17:20 unknown XXX[1753] <Warning>: flipping
Nov 8 19:17:20 unknown XXX[1753] <Warning>: --> dealloc <AVAudioPlayer: 0x6887530> (d2_s3_l3_q9.aif)
Nov 8 19:17:20 unknown XXX[1753] <Warning>: --> dealloc <AVAudioPlayer: 0x6887530> (d2_s3_l3_q9.aif)
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x68859f0 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x11ef30 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x1a6720 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x6872400 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
(...)
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x6872ed0 of class __NSCFDictionary autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x10cf80 of class __NSCFNumber autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x6850480 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x10a530 of class __NSCFNumber autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x1d15d0 of class __NSCFNumber autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x6884550 of class TFCrashHandler autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x685ec10 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:20 unknown UIKitApplication:com.bundle.name[0x2432][1753] <Notice>: objc[1753]: Object 0x6856270 of class __NSCFDictionary autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Nov 8 19:17:21 unknown com.apple.networkd[1763] <Notice>: main:212 networkd.1763 built Sep 16 2011 00:02:59
Nov 8 19:17:25 unknown ReportCrash[1764] <Notice>: Formulating crash report for process XXX[1753]
Nov 8 19:17:25 unknown com.apple.launchd[1] <Warning>: (UIKitApplication:com.bundle.name[0x2432]) Job appears to have crashed: Segmentation fault: 11
Nov 8 19:17:25 unknown SpringBoard[15] <Warning>: Application 'XXX' exited abnormally with signal 11: Segmentation fault: 11
Nov 8 19:17:25 unknown ReportCrash[1764] <Error>: Saved crashreport to /var/mobile/Library/Logs/CrashReporter/XXX_2011-11-08-191724_iKotapad.plist using uid: 0 gid: 0, synthetic_euid: 501 egid: 0
Редактировать:
Я думаю, ключевая часть здесь — это удвоенные логи в начале. Когда сбой не происходит, он появляется только один раз. И проблема может возникнуть из-за того, что dealloc
метод одного и того же объекта вызывается дважды.
Ответ №1:
Я бы посоветовал сначала позаботиться об этой autorelease
утечке из бассейна и посмотреть, останется ли проблема.
Комментарии:
1. Похоже, это проблема с пулом авторелиза в неосновном потоке, и поскольку я не выполняю никаких многопоточных действий в этом приложении и не использую фоновые задачи — я думаю, что это может быть проблемой не в моем коде…
2. Мне интересно, может ли это быть связано с тем, что я использую неатомные свойства в своем коде. Возможно, это могло вызвать удвоенный доступ к переменной?
3. Консоль, похоже, указывает, что код, запускающий ваш звук, выполняется дважды, но ссылается на один и тот же объект, который отлично работает, пока не придет время его освободить. Прокомментируйте одно из мест, где вы запускаете аудио, даже если вы думаете, что это единственное место, и посмотрите, вызывается ли оно дважды. Возможно, что событие, которое запускается в конце фильма, вызывается дважды, и в результате звук запускается дважды — попробуйте добавить логический флаг, чтобы процедура запуска звука выполнялась только один раз.
4. Возня с
nonatomic
может устранить симптоматический сбой, но не остановит проблему с воспроизведением звука дважды.5. У меня уже есть что-то подобное в моем коде… Я проигрываю там несколько аудиофайлов, один за другим. У меня есть аудиофайлы в массиве, и у меня есть индекс текущего воспроизводимого звука в переменной экземпляра. Итак, если этот метод, который вызывает фактическое воспроизведение звука, будет вызываться дважды в обычных условиях, он должен воспроизводить разные аудиофайлы, а не один и тот же…
Ответ №2:
У меня была аналогичная проблема с приложением для iPhone, запущенным в симуляторе iOS5. По-видимому, при такой настройке, если у вас есть автоматически выпущенный объект без определенного пула автоматического выпуска, система немедленно освободит этот объект и распечатает это сообщение: «…Объект 0x6872ed0 класса TheClass автоматически выпущен без пула на месте — просто утечка — прерывание objc_autoreleaseNoPool() для отладки «. В моем коде он освобождал объект еще до присвоения переменной, так что после этой строки у меня гарантированно была плохая память. Для исправления вам необходимо предоставить пул авторелиза … вы можете обернуть код, который выделяет эти объекты (на любом подходящем уровне) с помощью @autoreleasepool{ …}, например:
@autoreleasepool {
NSData *data = [NSData dataWithBytes:myBytes length:myLength];
//do something with data
}
Определив пул автоматического выпуска с помощью @autoreleasepool, он сохранит этот объект данных (не будет пытаться освободить его), пока вы затем используете этот объект.
Другим решением было бы выделить освобождаемые объекты с помощью метода, который не использует автоматическое освобождение. Я знаю, что с NSData [Данные NSData] вернут автоматически выпущенный объект, тогда как [[NSData alloc] init] не будет. Вероятно, есть аналоги с объектами, которые вы используете. Очевидно, что это возможно только в том случае, если вы контролируете распределение … если нет, вы, вероятно, застряли в определении пула автоматического выпуска.
Ответ №3:
Это может произойти только в симуляторе. Я столкнулся с аналогичной проблемой, которую не смог исправить, но обнаружил, что это происходит только в симуляторе, отлично работает на всех устройствах.