2015-03-09 17 views
7

Dostałem dziwną katastrofę EXC_BAD_ACCESS w metodzie Fundacji -[NSData(NSData) getBytes:length:]. Zdarza się to dość często, ale nie mogę uzyskać żadnych znaczących informacji ze śledzenia stosu. W moim kodzie nie ma połączeń z getBytes:length:, z wyjątkiem bibliotek o otwartym kodzie źródłowym (jeden w SDWebImage i jeden w SocketRocket), ale wygląda na to, że nie powodują one awarii.Nie można wyśledzić [NSData getBytes: length:] crash

Jedyną wskazówką jest to, że awaria występuje wewnątrz wątku com.apple.CFNetwork.addPersistCacheToStorageDaemon, ale nie mam pojęcia, o co chodzi. Czy ktoś może pomóc?

StackTrace z 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 

I jeszcze jedno (zdarza się rzadziej):

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

Czy dzieje się to w środowisku programistycznym? – zaph

+0

@Zaph: nie, nie mogłem odtworzyć go samodzielnie. Dzieje się tylko w produkcji. – Spail

+1

Przypuszczalnie "getData" otrzymał fałszywy adres bufora, ale kto byłby odpowiedzialny, trudno zgadnąć. Pamiętaj, że oba te przypadki dotyczą operacji z pamięcią podręczną URL. –

Odpowiedz

2

Domyślam się, że masz

  • niektóre __unsafe_unretained (czyli unavoidable dla setter Path [NSInvocation setArgument:atIndex:])
  • lub problem jak this jednej
  • lub (bardziej prawdopodobne) Â deadlock podczas performBlockAndWait (od Widziałem połączenia/timeout w stosie)

Kilka sugestii pokrewnych :

1) NSManagedObject, NSManagedObjectContext i NSPersistentStoreCoordinator (ze względu na krach na addPersistCacheToStorageDaemon) nie są wątku bezpieczne:

  • rozważyć tę opcję, jeśli używasz performBlockAndWait wysyłać wiadomości do swojej NSManagedObjectContext (więcej here i here) lub nested MOC.

2) CFNetwork jest klasa niższego poziomu, który jest owinięty przez NSURLConnection:

  • więc nie stosując NSURL? unikanie addObserver:self forKeyPath (KVO) na własność sesji NSURL?
2

Problem może być w rzeczywistości od SDWebImage cytat z tej strony:

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

Teraz, jeśli używasz AFNetworking aby ustawić obraz bezpośrednio z adresu URL za pomocą kategorię AFNetworking was mogą chcesz użyć alternatywnej metody, aby interweniować i zmieniać rozmiar obrazu. Poniższy kod to zrobi.

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 
}]; 

Chciałbym również sprawdzić aktualizacja powiązanych wywala:

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

Sprawdź, czy korzystasz z najnowszej wersji SDWebImage, w przeciwnym razie może trzeba sprawdzić starszych problemów.

3

Wraz z wprowadzeniem iOS 8 pojawiły się również nieoczekiwane błędy, o których również musimy pamiętać.

Aplikacje takie jak MIT Mobile, Mile Point również cierpią z powodu problemu podobnego do twojego, nie jest to jednak szeroko rozpowszechnione.

Oto linki błędów dla MIT & MilePoint.

com.apple.CFNetwork.addPersistCacheToStorageDaemon

CFNetwork jest niższy poziom API C i jest owinięte wyższej klasy warstwy, takich jak NSURLConnection.

więc awaria podczas operacji sieciowych

EXC_BAD_ACCESS

oznacza to, że wiadomość została wysłana na adres pamięci, gdzie nie ma instancją klasy, aby go wykonać. Tak więc wyniki "zły dostęp"

Kiedy to się stanie?

  1. Obiekt nie jest inicjowany
  2. obiekt jest już wydany
  3. coś innego, co nie jest bardzo prawdopodobne

Jak możemy rozwiązać ten problem?

  • Można złapać niektóre błędy (numer 2) poprzez umożliwienie NSZombie w Xcode

Włączanie NSZombie:

Gdy funkcja ta jest włączona, fikcyjny obiekt (zombie) jest przechowywany w miejscu każdego uwolnionego obiektu, umożliwiając w ten sposób debugowanie obiektów, które zostały już wydane.Bardzo proste, aby umożliwić:

  1. dwukrotnie kliknij plik wykonywalny w „wykonywalne” w Xcode
  2. Otwarte „argumenty” w zakładce „Zmienne do przedstawionych w środowisku” (jest to lista na dole, należy uważać, który z nich edit)
  3. kliknij przycisk „+”, a za nazwą zmiennej wpisać „NSZombieEnabled” i wartości „TAK”

teraz zamiast zastanawiać się, co się dzieje i jaki dokładnie przedmiot wyprodukowany problem , zobaczysz dokładnie, która klasa jest twórcą problemów, a i będziesz dość szybko debugować.

Uwaga: Nie zezwalaj na włączanie zombie po przesłaniu aplikacji do sklepu App Store. Poza tym dobrze jest je wyłączyć, jeśli naprawdę ich nie potrzebujesz.

  • Jeśli używasz bibliotek innych firm uprzejmie go zaktualizować do najnowszej

Uwaga:

Moja sugestia nigdy nie używać ramy osobę trzecią, chyba że jej nieuniknione, ponieważ sama biblioteka będzie miała błędy czasami który jest poza kontrolą programisty i czasami biblioteka byłaby aktualizowana późno do bieżącego SDK. Więcej informacji na ten temat można uzyskać pod adresem: here

Mam nadzieję, że to pomoże