2015-11-14 27 views
13

Moja aplikacja umożliwia użytkownikom edytowanie zdjęć przy użyciu frameworku Zdjęcia. Widzę niektóre raporty o awariach i wygląda na to, że awarie występują podczas generowania obrazu wyjściowego, ale nie jestem pewien, gdzie leży problem. Ta awaria występuje na wielu urządzeniach i wielu wersjach systemu iOS 9, w tym w najnowszej wersji 9.1. Ostatnie wywołanie, które moja aplikacja tworzy, to CGImageDestinationFinalize w celu utworzenia edytowanego obrazu NSData. Raporty o awariach pokazują, że połączenia są kontynuowane w przestrzeni CoreImage przed wystąpieniem awarii w programie GLTextureManager.Awaria po CGImageDestinationFinalize

Czy to może być problem z brakującą pamięcią? Czy widzisz problem? Jak można to rozwiązać?

odpowiedni kod z PhotoEditor.swift, wewnątrz funkcji fullImageOutput że nazywa się od editSingleAsset który pracuje w kolejce tła z QOS_CLASS_UTILITY:

let outputPhoto = //the generated CIImage that is the edited photo to be saved to disk 
let dataRef = CFDataCreateMutable(nil, 0) 

if let destination = CGImageDestinationCreateWithData(dataRef, "public.jpeg", 1, nil) { 
    struct ContextStruct { 
     static var ciContext: CIContext? = nil 
    } 
    if ContextStruct.ciContext == nil { 
     let eaglContext = EAGLContext(API: .OpenGLES2) 
     ContextStruct.ciContext = CIContext(EAGLContext: eaglContext) 
    } 
    let cgImage = ContextStruct.ciContext!.createCGImage(outputPhoto, fromRect: outputPhoto.extent) 

    CGImageDestinationAddImage(destination, cgImage, nil) 

    if CGImageDestinationFinalize(destination) { //FIXME: CRASH 
     //write to disk from dataRef etc 
    } 

} 

Wizualizacja raportu katastrofy:

enter image description here

crash szczegóły raportu:

Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000145201ac0 
Triggered by Thread: 7 

Thread 7 name: 
Thread 7 Crashed: 
0 libsystem_platform.dylib  0x0000000199e36220 _platform_memmove + 48 (memmove.s:220) 
1 CoreImage      0x0000000184e86e4c CI::GLTextureManager::texture_for_CGImage(CGImage*, CI::PixelFormat) + 372 (context-gles.cpp:910) 
2 CoreImage      0x0000000184e8a310 CI::GLContext::bind_textures(CI::SerialObjectPtrArray*, CI::Kernel*) + 240 (context-gles.cpp:3060) 
3 CoreImage      0x0000000184e899e0 CI::GLContext::render_apply_node(CI::Node const*, bool) + 160 (context-gles.cpp:2699) 
4 CoreImage      0x0000000184e897fc CI::GLContext::recursive_render(CI::Node*, bool) + 912 (context-gles.cpp:2379) 
5 CoreImage      0x0000000184e8a788 CI::GLContext::render(CI::Node*) + 180 (context-gles.cpp:2880) 
6 CoreImage      0x0000000184e9bfec CI::_get_bitmap(CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*) + 676 (render.cpp:2622) 
7 CoreImage      0x0000000184e9bc9c CI::image_get_bitmap(CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*, unsigned long) + 664 (render.cpp:2680) 
8 CoreImage      0x0000000184ea08e8 copyImageBlockSetOptsCallback(void*, CGImageProvider*, CGRect, CGSize, __CFDictionary const*) + 856 (imageProvider.h:143) 
9 CoreGraphics     0x0000000184af2198 CGImageProviderCopyImageBlockSet + 220 (CGImageProvider.c:500) 
10 ImageIO       0x0000000185baa41c GetBytesImageProvider + 484 (CGImagePixelDataProvider.c:382) 
11 ImageIO       0x0000000185c40440 _CGImagePluginWriteAppleJPEG + 2444 (imageAppleJPEG.c:2785) 
12 ImageIO       0x0000000185ba3020 CGImageDestinationFinalize + 724 (CGImageDestination.c:2119) 
13 MyAppNameHere     0x0000000100096468 _TFC11 MyAppNameHere 12PhotoEditor15fullImageOutputfS0_FT_GSqCSo22PHContentEditingOutput_ + 1272 (PhotoEditor.swift:71) 
14 MyAppNameHere     0x0000000100113310 _TFFFFFC11 MyAppNameHere 36PhotosPickerCollectionViewController16editSingleAssetFS0_FCSo7PHAssetT_U_FT_T_U0_FTGSqCSo21PHContentEditingInput_GVSs10DictionaryCSo8NSObjectPSs9AnyObject___T_U_FT_T_U_FT_T_ + 172 (PhotosPickerCollectionViewController.swift:851) 
15 libdispatch.dylib    0x0000000199c296e8 _dispatch_call_block_and_release + 24 (init.c:761) 
16 libdispatch.dylib    0x0000000199c296a8 _dispatch_client_callout + 16 (object.m:513) 
17 libdispatch.dylib    0x0000000199c37b40 _dispatch_root_queue_drain + 2140 (inline_internal.h:1063) 
18 libdispatch.dylib    0x0000000199c372dc _dispatch_worker_thread3 + 112 (queue.c:4250) 
19 libsystem_pthread.dylib   0x0000000199e3d470 _pthread_wqthread + 1092 (pthread.c:1990) 
20 libsystem_pthread.dylib   0x0000000199e3d020 start_wqthread + 4 (pthread_asm.s:191) 
+0

Dlaczego powinniśmy oczekiwać, że CGImageDestinationFinalize jest bezpieczna dla wątków? Jeśli wyjdziesz do głównego wątku, aby sfinalizować, czy awarie znikną? – matt

+0

@matt Nie mogłem odtworzyć tej awarii samodzielnie, jednak sfinalizowanie w głównej kolejce nie powoduje nowej awarii, ale powoduje zablokowanie głównego wątku w czasie, w którym to nastąpi - uniemożliwiając użytkownikowi anulowanie bieżącej operacji . – Joey

+0

@matt W przykładowym kodzie Apple SquareCam robią coś podobnego i wywołują 'CGImageDestinationFinalize' w kolejce szeregowej, którą utworzyli – Joey

Odpowiedz

0

To był znany problem w iOS 9, który został rozwiązany w iOS 10. Nie było nic złego w kodzie źródłowym.