Ege Akpinar
Ege Akpinar

Reputation: 3286

EXC_BAD_ACCESS when using dispatch_async

We have recently revised our threading mechanism in favour of using dispatch_async's in most places (after doing a lot of reading about NSOperation vs dispatch_async)*. Then our code started crashing with EXC_BAD_ACCESS in various parts of the code, always on the dispatch_async(queue,...) part, with no clear pattern. Usually happening after 20 minutes - 2 hours.

Our dispatch_async blocks were used to notify listeners, looked as follows:

NSMutableSet *_listeners; // Initialised elsewhere and filled with interested listeners
void(^block)(id listener); // Block to execute

@synchronized(_listeners) {
  for (id listener in _listeners) {
    dispatch_async_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // We used different queues for different listeners, but showing only one type of queue here for brevity
    dispatch_async(queue, ^{ // CRASHING LINE
      block(listener);
    });
  }
}

y common symptoms were:

(This is a self-answered question)

*We liked the simplicity of dispatch_async, didn't need the blocking / dependency features of NSOperationQueue's and we will be moving to C++ soon so wanted to stay low level.

Upvotes: 1

Views: 1556

Answers (1)

Ege Akpinar
Ege Akpinar

Reputation: 3286

After days of debugging, ensuring our thread objects were strongly retained, and trying various weak-strong combinations and thorough profiling using Instruments, we have come to the conclusion that this is an Apple bug (as also reported here) that only appears on recent iOS versions (iOS10 for us, but I reckon it will be present from the version when libBacktraceRecording.dylib started appearing).

Symptoms of:

  • Not reproducible on iOS8.x
  • Only happens when in debugging mode
  • EXC_BAD_ACCESS in random parts of the code, without any pattern

might indicate this.

Hope this is useful for others!

Upvotes: 5

Related Questions