2016-11-02 12 views
28

के कारण मैंने देखा है कि NSURLSessionDataDelegate लागू करने और एक कार्य शुरू करने से बहुत कभी-कभी एक EXC_BAD_ACCESS फेंक देते हैं। त्रुटि प्रदान करने वाली वास्तविक कॉलिंग विधि भिन्न होती है लेकिन हमेशा CFNetwork से आता है। अधिकांश भाग के लिए, कॉलिंग विधि NSURLSession delegate_dataTask:didReceiveData:completionHandler से आता है। मैंने नीचे दो अलग-अलग कॉलर्स के साथ दो क्रैश लॉग संलग्न किए हैं। मैंने NSURLSessionDataDelegate के कार्यान्वयन को भी संलग्न किया है।NSURLSession EXC_BAD_ACCESS

दुर्भाग्य से मैं मज़बूती से त्रुटि पुन: पेश नहीं कर सकते, तो मैं साझा करने के लिए एक उदाहरण स्क्रिप्ट नहीं है। Downloader ऑब्जेक्ट्स बनाना और शुरू करना अंततः त्रुटि उत्पन्न करेगा। ऐसा लगता है कि बड़ी फ़ाइलों के साथ अक्सर होता है। क्या मैंने यहां कुछ गलत लगाया है? क्या इस स्टैकट्रैक से डीबग करने का कोई अच्छा तरीका है?

मैंने उसी परिणाम के साथ आईओएस 10 और 10.1.1 पर परीक्षण किया है।

कार्यान्वयन:

class Downloader: NSObject, NSURLSessionDataDelegate { 
    private let url: String 
    var finished = false 
    let finishCondition = NSCondition() 

    init(url:String) { 
     self.url = url 
     super.init() 
    } 

    func start() { 
     let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
     let session = NSURLSession(configuration: config, 
           delegate: self, 
           delegateQueue: nil) 
     guard let u = NSURL(string: url) else { 
      return 
     } 
     let request = NSMutableURLRequest(URL: u) 
     let task = session.dataTaskWithRequest(request) 
     task.resume() 
    } 

    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, 
        didReceiveData data: NSData) { 
    } 

    func URLSession(session: NSURLSession, 
        task: NSURLSessionTask, 
        didCompleteWithError error: NSError?) { 
     session.invalidateAndCancel() 
    } 

    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, 
        didReceiveResponse response: NSURLResponse, 
             completionHandler: (NSURLSessionResponseDisposition) -> Void) { 
     completionHandler(NSURLSessionResponseDisposition.Allow) 
    } 

    func waitForFinish() { 
     finishCondition.lock() 
     while !finished { 
      finishCondition.wait() 
     } 
     finishCondition.unlock() 
    } 

    func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) { 
     finishCondition.lock() 
     finished = true 
     finishCondition.broadcast() 
     finishCondition.unlock() 
    } 
} 

क्रैश लॉग # 1:

* thread #5: tid = 0x25923, 0x0000000100042e8c libBacktraceRecording.dylib`__gcd_queue_item_enqueue_hook_block_invoke, queue = 'com.apple.NSURLSession-work', stop reason = EXC_BAD_ACCESS (code=1, address=0xf8686a68b98c6ec8) 
    * frame #0: 0x0000000100042e8c libBacktraceRecording.dylib`__gcd_queue_item_enqueue_hook_block_invoke 
    frame #1: 0x000000010004241c libBacktraceRecording.dylib`gcd_queue_item_enqueue_hook + 232 
    frame #2: 0x000000010065dee8 libdispatch.dylib`_dispatch_introspection_queue_item_enqueue_hook + 40 
    frame #3: 0x000000010063cba4 libdispatch.dylib`_dispatch_queue_push + 196 
    frame #4: 0x000000018ba50500 Foundation`iop_promote_qos_outward + 112 
    frame #5: 0x000000018ba4e524 Foundation`-[NSOperation setQualityOfService:] + 168 
    frame #6: 0x000000018b9d7714 Foundation`-[NSOperationQueue addOperationWithBlock:] + 76 
    frame #7: 0x000000018b73f82c CFNetwork`-[NSURLSession delegate_dataTask:didReceiveData:completionHandler:] + 208 
    frame #8: 0x000000018b5a2c5c CFNetwork`-[__NSCFLocalSessionTask _task_onqueue_didReceiveDispatchData:completionHandler:] + 276 
    frame #9: 0x000000018b5a5474 CFNetwork`-[__NSCFLocalSessionTask connection:didReceiveData:completion:] + 164 
    frame #10: 0x000000018b647bf0 CFNetwork`__48-[__NSCFURLLocalSessionConnection _tick_running]_block_invoke + 120 
    frame #11: 0x000000018b647b60 CFNetwork`-[__NSCFURLLocalSessionConnection _tick_running] + 344 
    frame #12: 0x000000018b648c74 CFNetwork`-[__NSCFURLLocalSessionConnection _didReceiveData:] + 412 
    frame #13: 0x000000018b64af8c CFNetwork`SessionConnectionLoadable::_loaderClientEvent_DidReceiveData(__CFArray const*) + 52 
    frame #14: 0x000000018b6f823c CFNetwork`___ZN19URLConnectionLoader19protocolDidLoadDataEPK8__CFDatax_block_invoke_2 + 44 
    frame #15: 0x000000018b64b58c CFNetwork`___ZN25SessionConnectionLoadable21withLoaderClientAsyncEU13block_pointerFvP21LoaderClientInterfaceE_block_invoke + 32 
    frame #16: 0x000000010063125c libdispatch.dylib`_dispatch_call_block_and_release + 24 
    frame #17: 0x000000010063121c libdispatch.dylib`_dispatch_client_callout + 16 
    frame #18: 0x000000010063eb54 libdispatch.dylib`_dispatch_queue_serial_drain + 1136 
    frame #19: 0x0000000100634ce4 libdispatch.dylib`_dispatch_queue_invoke + 672 
    frame #20: 0x0000000100640e6c libdispatch.dylib`_dispatch_root_queue_drain + 584 
    frame #21: 0x0000000100640bb8 libdispatch.dylib`_dispatch_worker_thread3 + 140 
    frame #22: 0x000000018a01e2b8 libsystem_pthread.dylib`_pthread_wqthread + 1288 
    frame #23: 0x000000018a01dda4 libsystem_pthread.dylib`start_wqthread + 4 

क्रैश लॉग # 2:

* thread #12: tid = 0x2521f, 0x000000010010ae8c libBacktraceRecording.dylib`__gcd_queue_item_enqueue_hook_block_invoke, queue = 'com.apple.CFNetwork.Connection', stop reason = EXC_BAD_ACCESS (code=1, address=0xd00f524835000200) 
     * frame #0: 0x000000010010ae8c libBacktraceRecording.dylib`__gcd_queue_item_enqueue_hook_block_invoke 
     frame #1: 0x000000010010a41c libBacktraceRecording.dylib`gcd_queue_item_enqueue_hook + 232 
     frame #2: 0x0000000100759ee8 libdispatch.dylib`_dispatch_introspection_queue_item_enqueue_hook + 40 
     frame #3: 0x0000000100738ba4 libdispatch.dylib`_dispatch_queue_push + 196 
     frame #4: 0x00000001975ccb3c libnetwork.dylib`nw_connection_read + 448 
     frame #5: 0x00000001975d938c libnetwork.dylib`tcp_connection_read + 168 
     frame #6: 0x000000018b719d54 CFNetwork`TCPIOConnection::read(unsigned long, unsigned long, void (dispatch_data_s*, CFStreamError) block_pointer) + 172 
     frame #7: 0x000000018b782af4 CFNetwork`HTTPEngine::_getBodyIntelligently(void (dispatch_data_s*, CFStreamError, bool) block_pointer) + 816 
     frame #8: 0x000000018b780d0c CFNetwork`HTTPEngine::_readBodyStartNextRead() + 76 
     frame #9: 0x000000018b783664 CFNetwork`___ZN10HTTPEngine21_getBodyIntelligentlyEU13block_pointerFvP15dispatch_data_s13CFStreamErrorbE_block_invoke.56 + 344 
     frame #10: 0x000000018b719f64 CFNetwork`___ZN15TCPIOConnection4readEmmU13block_pointerFvP15dispatch_data_s13CFStreamErrorE_block_invoke + 480 
     frame #11: 0x000000010072d25c libdispatch.dylib`_dispatch_call_block_and_release + 24 
     frame #12: 0x000000010072d21c libdispatch.dylib`_dispatch_client_callout + 16 
     frame #13: 0x000000010073ab54 libdispatch.dylib`_dispatch_queue_serial_drain + 1136 
     frame #14: 0x0000000100730ce4 libdispatch.dylib`_dispatch_queue_invoke + 672 
     frame #15: 0x000000010073ce6c libdispatch.dylib`_dispatch_root_queue_drain + 584 
     frame #16: 0x000000010073cbb8 libdispatch.dylib`_dispatch_worker_thread3 + 140 
     frame #17: 0x000000018a01e2b8 libsystem_pthread.dylib`_pthread_wqthread + 1288 
     frame #18: 0x000000018a01dda4 libsystem_pthread.dylib`start_wqthread + 4 

अद्यतन: मैं अब अर्द्ध मज़बूती से इस त्रुटि से पुन: पेश कर सकते हैं आईओएस सिम्युलेटर में नीचे चिपका हुआ लूप चला रहा है। यह आईओएस 9.3 पर नहीं होता है। यदि आप नीचे दिए गए कोड को चलाते हैं, तो एक मिनट के भीतर आपको त्रुटि प्राप्त होनी चाहिए। चूंकि यह एक डिवाइस की तुलना में सिम्युलेटर में होने की संभावना है, इसलिए मुझे लगता है कि यह एक समवर्ती मुद्दा है जो अधिक प्रसंस्करण शक्ति/कोर के साथ अधिक संभावना बन जाता है। त्रुटि पुन: पेश करने के लिए, इस चलाएँ:

var i = 0 
while true { 
    print("running: \(i)") 
    // random url, larger files seem more likely to cause error 
    let url = "http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/3340/33409.ts" 
    let c = Downloader(url: url) 
    c.start() 
    c.waitForFinish() 
    i += 1 
} 
+2

आईओएस 10 में यह देखकर 9.3 सिम्युलेटर भी नहीं। वही लक्षण, एक ही बैकट्रैस, कोई सुराग नहीं। – Icydog

+2

मुझे 10.0 सिम्युलेटर '' '* थ्रेड # 64: tid = 0x5e3688, 0x000000010717deac libBacktraceRecording.dylib'__gcd_queue_item_enqueue_hook_block_invoke + 4, queue = 'com.apple.network.connections' पर एक समान क्रैश दिखाई दे रहा है, कारण = EXC_BAD_ACCESS (कोड रोकें = EXC_I386_GPFLT) '' – yuf

+1

मुझे खुशी है कि मैं अकेला नहीं हूं। क्या इसे डीबग करने का कोई अच्छा तरीका है? – oliveroneill

उत्तर

43

ऐप्पल तकनीकी सहायता के साथ बात करने के बाद हमने पुष्टि की कि यह libBacktraceRecording.dylib लाइब्रेरी के भीतर एक बग है, जिसका उपयोग एक्सकोड के भीतर डीबगिंग के लिए किया जाता है। मैंने एक बग रिपोर्ट दायर की है और कहा गया है कि यह किसी उपयोगकर्ता डिवाइस पर क्रैश नहीं होगा क्योंकि यह एक डीबग त्रुटि है जो पुस्तकालय के भीतर होती है जो अधिकांश उपयोगकर्ताओं के उपकरणों पर मौजूद नहीं होती है।

+1

क्या आप बग रिपोर्ट के बारे में एक लिंक या अधिक जानकारी साझा कर सकते हैं? तो अन्य इसकी प्रगति देख सकते हैं? और उत्सुक है कि आप एप्पल तकनीकी सहायता के संपर्क में कैसे पहुंचे? क्या वे उत्तरदायी हैं? – Honey

+1

मैंने इसे अभी तक ओपनराडर पर नहीं रखा है, लेकिन ऐप्पल आम तौर पर प्रगति पर बहुत कम प्रतिक्रिया देता है।आप https://developer.apple.com/support/technical/ के माध्यम से डेवलपर तकनीकी सहायता के लिए ऐप्पल से संपर्क कर सकते हैं। वे आमतौर पर अगले कारोबारी दिन, बहुत सुंदर उत्तरदायी द्वारा जवाब दिया। – oliveroneill

+2

मुझे सिएरा में मैक पर सटीक वही दुर्घटना मिलती है; एक ही लक्षण, (NSCCADctionLoader कोड में EXC_BAD_ACCESS गहरा है, लेकिन केवल एक्सकोड डीबग सत्र से); गार्ड मॉलोक, पता सैनिटाइजर इत्यादि में से कोई भी इसे ठीक करता है। मैक – mackworth

1

Zombies साधन में चलाने की कोशिश करें। मेरा अनुमान है कि आपके Downloader क्लास इंस्टेंस को निरस्त कर दिया जा रहा है जबकि NSURL सत्र चल रहा है, इसलिए जब यह आपके didReceiveData विधि को कॉल करने के लिए जाता है, तो पहले आपके ऑब्जेक्ट द्वारा कब्जा कर लिया गया स्मृति कुछ और होता है। (यही एक ज़ोंबी है।)

+2

मैं ज़ोंबी इंस्ट्रूमेंट के भीतर त्रुटि को फिर से बनाने में असमर्थ था। हालांकि "संपादन योजना" से "ज़ोंबी ऑब्जेक्ट्स" को चालू करने से किसी भी ज़ोंबी ऑब्जेक्ट चेतावनियों को आउटपुट किए बिना एक ही त्रुटि उत्पन्न हुई। क्या इन दोनों के बीच कोई अंतर है? – oliveroneill

+1

मुझे एक समान दुर्घटना दिखाई दे रही है और जब यह हुआ, तो मेरे पास ज़ोंबी थी, लेकिन इसमें कुछ भी नहीं मिला। – yuf

+0

मैं पुष्टि कर सकता हूं कि यह अभी भी Xcode 9, बीटा 5 सिएरा 10.12.5 पर होता है। – manmal