NSURLSession's `getTasksWithCompletionHandler:`'s `completionHandler` is not called on the delegate queue

Originator:henriqueponde90
Number:rdar://33838468 Date Originated:08/10/2017
Status:Open Resolved:No
Product: Product Version:
Classification: Reproducible:
 
Area:
Foundation

Summary:
We have crashes in the wild (user's phones) on an assert that we have on the first line of our `completionHandler`:

```
[session getTasksWithCompletionHandler:^(NSArray<NSURLSessionDataTask *> *dataTasks,
                                             NSArray<NSURLSessionUploadTask *> *uploadTasks,
                                             NSArray<NSURLSessionDownloadTask *> *downloadTasks) {
            NSCAssert([[NSOperationQueue currentQueue] isEqual:_queue], @"Delegate method not called on delegate queue");
```

And from the code it is not possible that `_queue` is nil, and the session is being created with `_queue` being passed into the call:

```
        return [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:delegate delegateQueue:queue];
```

This is really bad for us because our code uses the fact that all these completion blocks are called in the same serial queue, so that we can reason about the code in a sane way. If we don't have the guarantee of ordering, then the code becomes much harder to reason about and debug.

Steps to Reproduce:
We have code that is available to users in the wild that contains the assert on the completion block that we are on the correct queue. That assert is necessary because we depend on the serialization of the callbacks in order to make sense of the code and behave accordingly.

Expected Results:
We'd expect the blocks to always run in the correct queue that the url session was initialized with, since that is the documented behavior.

Observed Results:
We see that sometimes, in the wild, on user's crash reports, the queue is not correct and in fact the block is being called on the wrong queue, therefore we are crashing and getting these reports. Have not been able to reproduce that locally.

Version:
iOS/10.3.2
iOS/10.3.1
iOS/10.2.1
iOS/9.3.5
iOS/10.3.3
iOS/10.2
iOS/10.0.2
iOS/10.1.1
iOS/10.3
iOS/10.0.1
iOS/11.0
iOS/9.3.2
iOS/9.3.4
iOS/10.1
iOS/10.0
iOS/9.2.1
iOS/9.3.3
iOS/9.3.1
iOS/9.2
iOS/9.1
iOS/9.0.2

Notes:
We have these crashes happening in the wild but they don't seem to be deterministic, so I'd say it's probably a race condition and therefore very hard to debug.

I came to the networking labs on WWDC and talked to Steve about it, he looked at the code and seemed to imply that it is possible that in a change/rewrite this behavior was introduced. He told me to file a rdar and mention him here

Configuration:

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!