NSURLSession causing EXC_BAD_ACCESS

I've noticed that implementing `NSURLSessionDataDelegate` and starting a task will very occasionally will throw an EXC_BAD_ACCESS. The actual calling method that gives the error seems to vary but always comes from `CFNetwork`. For the most part, the calling method comes from `NSURLSession delegate_dataTask:didReceiveData:completionHandler`. I've attached a crash log below. I've also attached my implementation of `NSURLSessionDataDelegate`.


I can semi-reliably recreate this by running the loop below in the Simulator. It also happens on actual devices, but is much more likely on the Simuatlor. Which makes me think that it's a concurrency issue, affected by the number of cores/processing power. It does seem to happen more often with larger files. Have I implemented something wrong here? Is there a good way to debug from this stacktrace?


I've tested on iOS10 and 10.1.1 with the same results. This does not occur on iOS 9.3.


To reproduce, run this in the Simulator for about two minutes (you must also include the Downloader class below):

var i = 0
while true {
    print("conn \(i)")
    let url = "http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/3340/33409.ts"
    let c = Downloader(url: url)
    c.start()
    c.waitForFinish()
    i += 1
}

Implementation:

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()
    }
}


Crash log #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

why no one . answer it ......


It happends in my app ,😢

There are reports floating 'round the net that this is a bug in the

libBacktraceRecording.dylib
debugging framework itself:

http://stackoverflow.com/questions/40371536/nsurlsession-causing-exc-bad-access/40536997#40536997

After speaking with Apple Technical Support we confirmed that it's a bug within the
libBacktraceRecording.dylib
library, which is used for debugging within Xcode. I have filed a bug report and have been told that it won't crash on a users device since this is a debug error that occurs within a library not present on most users' devices.

(This appears to be a followup to the exact same same question posted on StackOverflow!)


In my own app where I've encountered this, I run about 80 data tasks / second, and I reliably saw this occur within five hours, every time (iOS 10.2, while running in debug mode connected to XCode 8.2.1). I sent the app to an iOS 10.3 device running standalone, and it's been running for 25 hours so far with no crashes. Whether that's because it's 10.3, or is running standalone, I can't say for certain, but in any event I didn't change my code, and it's working.


In short, if you're seeing

libBacktraceRecording.dylib
at the top of your stack trace, it's probably this, and likely not an error in your code.
NSURLSession causing EXC_BAD_ACCESS
 
 
Q