2013-09-13 2 views
2

я застрял в следующем докладе аварии:Плохого выравнивания памяти IOS

Date/Time:  2013-09-12 22:39:54 +0000 
OS Version:  iPhone OS 6.1.3 (10B329) 
Report Version: 104 

Exception Type: SIGSEGV 
Exception Codes: SEGV_ACCERR at 0xa0000008 
Crashed Thread: 0 

Thread 0 Crashed: 
0 libobjc.A.dylib      0x39a3c564 _cache_getImp + 4 
1 libobjc.A.dylib      0x39a3e1d7 class_respondsToSelector + 31 
2 CoreFoundation      0x31b96605 objectIsKindOfClass + 37 
3 CoreFoundation      0x31b9635d __handleUncaughtException + 69 
4 libobjc.A.dylib      0x39a41a65 _objc_terminate() + 129 
5 libc++abi.dylib      0x3948e07b safe_handler_caller(void (*)()) + 79 
6 libc++abi.dylib      0x3948e114 std::terminate() + 20 
7 libc++abi.dylib      0x3948f599 __cxa_current_exception_type + 1 
8 libobjc.A.dylib      0x39a419d1 objc_exception_rethrow + 13 
9 CoreFoundation      0x31adcf21 CFRunLoopRunSpecific + 457 
10 CoreFoundation      0x31adcd49 CFRunLoopRunInMode + 105 
11 GraphicsServices     0x356a82eb GSEventRunModal + 75 
12 UIKit        0x339f2301 UIApplicationMain + 1121 
13 Our App        0x0003bc27 main (main.m:15) 

После различных попыток исправить ошибку вызывает эту ошибку, я все время получаю эту crashlog снова и снова от PLCrashReporter (от нашего AdHoc строит из бета-тестеров). Различные коды исключений варьируются от SIGSEGV/SEGV_ACCERR к SIGBUS/BUS_ADRALN к EXC_BAD_ACCESS/KERN_INVALID_ADDRESS

Я использую rapidjson library на прошивке (ARMv7 и armv7s) с отступом исправлением, как описан here (#8) и я использую Objective-C во время выполнения функции добавить реализацию метода во время выполнения (используя class_addMethod).

Наш код существует в основном с кодом Objective-C с некоторыми Obj-C++ и некоторыми C-кодом. Управление памятью осуществляется с помощью ARC, за исключением частей Obj-C++ и C, которые обрабатываются вручную. Я заглянул в каждый malloc/free call, и я широко использовал libgmalloc для определения проблем памяти, но нет ничего, что не кажется мне правильным.

Я не могу воспроизвести этот crashlogs самостоятельно, а не в режиме отладки или выпуска, но наши бета-тестеры продолжают посылать мне этот crashlog раз в то время (1 из примерно 50 запусков). Поскольку наш продукт (надеюсь) будет работать на многих устройствах iOS в ближайшее время, это не то, что мы можем сломать.

После прочтения большого количества статей управления памятью я подозреваю, что эта проблема вызвана неправильным выравниванием памяти. Поэтому я подозреваю, что quickjson стал причиной этой ошибки. Отсутствие знаний об выравнивании памяти на iOS/armv7 не позволяет мне исправить этот краш-лог. Может ли кто-нибудь объяснить мне больше об этой теме на iOS? Или я ищу не в том месте, и это еще одна проблема с памятью? Надеюсь, кто-то может указать мне в правильном направлении.

Если вам нужна дополнительная информация, я рад предоставить ее. Примечание: Я не ищу ответы, используя JSONKit или другую библиотеку для замены quickjson. Спасибо :)

ответ

2

Этот вопрос был ранее адресованным здесь: https://devforums.apple.com/message/807860

Короче говоря, исходное исключение Objective-C было выпущено (например, с помощью autorelease пула) до причем разыменовывается в неперехваченном обработчике исключений. Таким образом, __handleUncaughtException() разыскивает теперь мертвый указатель, и вы видите крах в вашем обработчике исключений.

+0

Большое спасибо, это действительно было причиной. Я был совершенно не в том направлении, искал ошибку. Теперь я могу воспроизвести эту ошибку в отладчике :) –

1

Во-первых, адрес 0xa0000008 не выглядит криво, и SEGV_ACCERR не означает проблемы с выравниванием, но проблемы с правами доступа к памяти (от Sys/signal.h):

#define SEGV_ACCERR  2  /* [XSI] invalid permission for mapped object */ 

Учитывая вас используют class_addMethod(), а авария находится в _cache_getImp(), что является частью процесса получения, мое необоснованное подозрение будет заключаться в том, что вы передали некоторые недействительные указатели на class_addMethod() или позже перезаписали эту информацию.

Кое-что, чтобы проверить, будет ли вы использовать глобальные или malloc() ed memory, потому что функции выполнения не делают для вас копии.

Во-вторых, краш, который вы видите, является вторичным, вы сбой при запуске обработчика исключений верхнего уровня, который уже завершает (_objc_terminate()) вашу программу из более раннего исключения, но в этом случае это не сигнал Unix, но исключение Objective-C: objc_exception_rethrow().

Таким образом, вам, вероятно, необходимо сначала выяснить эту первичную ошибку, например, из журналов исключения (во многих случаях просто во многих случаях недостаточно backtrace).

+0

Спасибо за подсказки, я собираюсь изучить это. В то же время, есть ли у вас какие-либо рекомендации по извлечению журналов исключений? Должен ли я использовать свое собственное uncaughtException вместо PLCrashReporter? Какие свойства объекта NSException должны содержать необходимую информацию? –

+0

Похоже, что вторичная авария действительно может быть в PLCrashReporter. Вы пробовали просто удалить его? – mpw

+0

PLCrashReporter не отображается в данной обратной линии; эта проблема возникает до участия PLCrashReporter. – landonf

Смежные вопросы