2015-03-09 4 views
7

У меня возникла странная авария EXC_BAD_ACCESS внутри метода Foundation -[NSData(NSData) getBytes:length:]. Это происходит довольно часто, но я не могу получить какую-либо значимую информацию из трассировки стека. В моем коде нет вызовов getBytes:length:, за исключением библиотек с открытым исходным кодом (один из SDWebImage и один в SocketRocket), но похоже, что они не вызывают аварии.Невозможно отследить [NSData getBytes: length:] crash

Единственный намек на то, что авария происходит внутри com.apple.CFNetwork.addPersistCacheToStorageDaemon, но я понятия не имею, о чем это. Может кто-нибудь помочь?

StackTrace из Crashlytics:

Thread : Crashed: com.apple.CFNetwork.addPersistCacheToStorageDaemon 
0 libsystem_platform.dylib  0x3044a208 _platform_memmove$VARIANT$CortexA9 + 160 
1 Foundation      0x22df9167 -[NSData(NSData) getBytes:length:] + 118 
2 Foundation      0x22df9167 -[NSData(NSData) getBytes:length:] + 118 
3 Foundation      0x22e21a1b -[NSData(NSData) replacementObjectForCoder:] + 134 
4 Foundation      0x22dc2aff -[NSXPCEncoder _replaceObject:] + 90 
5 Foundation      0x22e240dd -[NSXPCEncoder _encodeArrayOfObjects:forKey:] + 192 
6 Foundation      0x22e212ff -[NSDictionary(NSDictionary) encodeWithCoder:] + 922 
7 Foundation      0x22dc32c9 -[NSXPCEncoder _encodeObject:] + 604 
8 Foundation      0x22dc379d encodeInvocationArguments + 460 
9 Foundation      0x22dc3455 -[NSXPCEncoder encodeInvocation:] + 360 
10 Foundation      0x22dc32c9 -[NSXPCEncoder _encodeObject:] + 604 
11 Foundation      0x22dc2335 -[NSXPCConnection _sendInvocation:proxyNumber:remoteInterface:withErrorHandler:timeout:userInfo:] + 1860 
12 Foundation      0x22dd2823 -[NSXPCConnection _sendInvocation:proxyNumber:remoteInterface:withErrorHandler:] + 58 
13 Foundation      0x22dd27db -[_NSXPCDistantObjectWithError forwardInvocation:] + 114 
14 CoreFoundation     0x2217e831 ___forwarding___ + 352 
15 CoreFoundation     0x220afb88 _CF_forwarding_prep_0 + 24 
16 CFNetwork      0x21c52ac9 -[NSURLStorage_CacheClient addCachedResponseWithDictionary:key:] + 120 
17 CFNetwork      0x21c21e29 ___ZN12__CFURLCache23CreateAndStoreCacheNodeEP16__CFURLCacheNodePK20_CFCachedURLResponsePK10__CFStringPK13_CFURLRequestPKvbRb_block_invoke + 1576 
18 libdispatch.dylib    0x302cf423 _dispatch_call_block_and_release + 10 
19 libdispatch.dylib    0x302d95d9 _dispatch_queue_drain$VARIANT$mp + 948 
20 libdispatch.dylib    0x302d90a9 _dispatch_queue_invoke$VARIANT$mp + 84 
21 libdispatch.dylib    0x302db0d3 _dispatch_root_queue_drain + 330 
22 libdispatch.dylib    0x302dc1fb _dispatch_worker_thread3 + 106 
23 libsystem_pthread.dylib  0x3044ce25 _pthread_wqthread + 668 

И еще один (бывает реже):

Thread : Crashed: com.apple.CFNetwork.addPersistCacheToStorageDaemon 
0 libsystem_platform.dylib  0x000000019344d300 _platform_memmove + 176 
1 Foundation      0x0000000182dfce18 -[NSData(NSData) getBytes:length:] + 172 
2 Foundation      0x0000000182dfce18 -[NSData(NSData) getBytes:length:] + 172 
3 Foundation      0x0000000182e2ae3c -[NSData(NSData) replacementObjectForCoder:] + 160 
4 Foundation      0x0000000182dbd320 -[NSXPCEncoder _replaceObject:] + 120 
5 Foundation      0x0000000182e2dac8 -[NSXPCEncoder _encodeArrayOfObjects:forKey:] + 256 
6 Foundation      0x0000000182e2a544 -[NSDictionary(NSDictionary) encodeWithCoder:] + 1016 
7 Foundation      0x0000000182dbdd10 -[NSXPCEncoder _encodeObject:] + 716 
8 Foundation      0x0000000182dbe2e8 encodeInvocationArguments + 508 
9 Foundation      0x0000000182dbdee4 -[NSXPCEncoder encodeInvocation:] + 412 
10 Foundation      0x0000000182dbdd10 -[NSXPCEncoder _encodeObject:] + 716 
11 Foundation      0x0000000182dbcb0c -[NSXPCConnection _sendInvocation:proxyNumber:remoteInterface:withErrorHandler:timeout:userInfo:] + 2196 
12 CoreFoundation     0x0000000181fde230 ___forwarding___ + 440 
13 CoreFoundation     0x0000000181ee2b6c _CF_forwarding_prep_0 + 92 
14 CFNetwork      0x000000018199c908 ___ZN12__CFURLCache23CreateAndStoreCacheNodeEP16__CFURLCacheNodePK20_CFCachedURLResponsePK10__CFStringPK13_CFURLRequestPKvbRb_block_invoke + 1976 
15 libdispatch.dylib    0x00000001932793ac _dispatch_call_block_and_release + 24 
16 libdispatch.dylib    0x000000019327936c _dispatch_client_callout + 16 
17 libdispatch.dylib    0x00000001932834c0 _dispatch_queue_drain + 1216 
18 libdispatch.dylib    0x000000019327c474 _dispatch_queue_invoke + 132 
19 libdispatch.dylib    0x0000000193285224 _dispatch_root_queue_drain + 664 
20 libdispatch.dylib    0x000000019328675c _dispatch_worker_thread3 + 108 
21 libsystem_pthread.dylib  0x00000001934552e4 _pthread_wqthread + 816 
+0

Это происходит в среде разработки? – zaph

+0

@ Zaph: nah, не смог воспроизвести его сам. Происходит только в производстве. – Spail

+1

Предположительно, 'getData' был передан адрес фиктивного буфера, но кто был бы ответственен, трудно догадаться. Обратите внимание, что оба случая включают операции с кешем URL. –

ответ

2

Я предполагаю, что у вас есть

  • некоторые __unsafe_unretained (то есть unavoidable для сеттер Путь [NSInvocation setArgument:atIndex:])
  • или вопрос, как this один
  • или (скорее) а deadlock во время performBlockAndWait (так как я видел соединение/тайм-аут в стеке)

Пару связанных предложений :

1) NSManagedObject, NSManagedObjectContext и NSPersistentStoreCoordinator (при аварии на addPersistCacheToStorageDaemon) не являются поточно:

  • считают это, если вы используете performBlockAndWait для отправки сообщений на ваш NSManagedObjectContext (более here и here) или nested MOC.

2) CFNetwork является классом более низкого уровня, который обернут в NSURLConnection:

  • поэтому не используя NSURL? избегая addObserver:self forKeyPath (KVO) в собственность сессии NSURL?
2

Вопрос может быть на самом деле из SDWebImage цитата с этого сайта:

http://webcache.googleusercontent.com/search?q=cache:BCShJT0ZrvoJ:quabr.com/15786084/uicollectionview-bad-acces-on-uicollectionviewdata-setlayoutattributesatglo+&cd=7&hl=fr&ct=clnk&gl=jp

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

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:imageURL]; 
[request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; 

[imageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { 
    // resize image 
    // set image on imageView 
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { 
    // handle error 
}]; 

Я хотел бы также проверить эту страницу для родственных аварий:

https://github.com/rs/SDWebImage/issues?q=is%3Aopen+is%3Aissue+label%3Acrash

Проверьте, если вы используете последнюю версию SDWebImage, в противном случае вы, возможно, придется проверить старые проблемы.

3

С введением iOS 8 происходит непредвиденная ошибка, и мы также должны помнить об этом.

Приложения, такие как MIT Mobile, Mile point также страдают от проблемы, подобной вашей, это пока не широко распространено.

Здесь приведены ссылки на ошибки для MIT & MilePoint.

com.apple.CFNetwork.addPersistCacheToStorageDaemon

CFNetwork ниже уровня C API и он обернут более высокого класса уровня, как NSURLConnection.

так происходит сбой во время работы в сети

EXC_BAD_ACCESS

Это означает, что сообщение было отправлено на адрес памяти, где нет никакого экземпляра класса для выполнения. Таким образом, получается «плохой доступ»

Когда это произойдет?

  1. Объект не инициализируется
  2. объект, уже выпущен
  3. что-то другое, что не очень вероятно, произойдет

Как мы можем решить эту проблему?

  • Вы можете поймать некоторые из ошибок (номер 2) Включение NSZombie в Xcode

Включение NSZombie:

Когда эта функция включена, фиктивный объект (зомби) хранится на месте каждого выпущенного объекта, что позволяет отлаживать уже выпущенные объекты.Очень легко включить:

  1. Дважды щелкните исполняемый файл в «Исполняемые» в XCode
  2. Open «Аргументы» на вкладке В «Переменные, которые будут установлены в окружающей среде» (это список в нижней части, будьте осторожны который один вам редактировать)
  3. нажмите на кнопку «+» и имя переменной введите «NSZombieEnabled», а значение «YES»

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

Примечание: Не оставляйте зомби включенными при отправке приложения в магазин приложений. Кроме того, это хорошая практика, чтобы отключить их, если они вам действительно не нужны.

  • Если вы используете сторонние библиотеки любезно обновить его до последней

Примечание:

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

Надеюсь, это поможет

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