Xcode 7 and com.apple.CoreData.ConcurrencyDebug violation

Running our iOS app in Xcode 7 with com.apple.CoreData.ConcurrencyDebug set results in a multithreading violation:


CoreData`+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]


on an iPhone 5S running iOS 8.4.1.


This does not occur on the same device when using Xcode 6.4.

The app also runs okay when run outside xcode.


Anyone have insight into why Xcode 7 would introduce this problem?

Thanks in advance

Replies

Any news with this? We're experiencing this on devices running iOS 8 while debugging with Xcode 7. Doesn't occur in simultor or when built using Xcode 6.

I can confirm we see the same behaviour. The code was OK under this flag before we switched to Xcode 7.

Thanks for the comments.

I've submitted a bug report.

Can you add a full crash report and / or 'thread backtrace all' print out to your bug report ? There isn't much to go on here. The assertions are implemented in the framework in the OS version, and shouldn't be effected by Xcode versions other than using a new Xcode to build for a new OS or simulator.


These assertions were improved in iOS 9, and may detect previously illegal but asymptomatic issues.

Attached a file with the output from 'thread backtrace all' to the bug report.


Note that we've only experienced this on an iOS 8.4.1 device and haven't seen it on iOS 9 devices.


Thanks for looking into this.

I'm also seeing this behavior.


The assertion is triggered with Xcode 7 and 8.4 simulator. 9.0 and 9.1 do not trigger the assertion. Xcode 6.4 also does not trigger the assertion.


The Process by Queue view shows:


#0 0x0000000112181114 in +[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__] ()
#1 0x00000001120d17d1 in -[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore] ()
#2 0x00000001120f0a14 in -[_PFManagedObjectReferenceQueue _processReferenceQueue:] ()
#3 0x0000000112188f8c in __89-[NSManagedObjectContext(_NSInternalNotificationHandling) _registerAyncReferenceCallback]_block_invoke ()
#4 0x0000000112116a79 in developerSubmittedBlockToNSManagedObjectContextPerform ()
#5 0x0000000112acb614 in _dispatch_client_callout ()
#6 0x0000000112ab26a7 in _dispatch_queue_drain ()
#7 0x0000000112ab1cc0 in _dispatch_queue_invoke ()
#8 0x0000000112ab53b9 in _dispatch_root_queue_drain ()
#9 0x0000000112ab6b17 in _dispatch_worker_thread3 ()
#10 0x0000000112e394f2 in _pthread_wqthread ()
#11 0x0000000112e37375 in start_wqthread ()
Enqueued from NSOperationQueue 0x7ffdd4486810 :: NSOperation 0x7ffdd1e8af50 (QOS: USER_INITIATED) (Thread 4)Queue : NSOperationQueue 0x7ffdd4486810 :: NSOperation 0x7ffdd1e8af50 (QOS: USER_INITIATED) (serial)
#0 0x0000000112aaf43f in _dispatch_barrier_async_f ()
#1 0x0000000112185f68 in -[NSManagedObjectContext performWithOptions:andBlock:] ()
#2 0x0000000112188f2d in -[NSManagedObjectContext(_NSInternalNotificationHandling) _registerAyncReferenceCallback] ()
#3 0x00000001120ef629 in -[_PFArray dealloc] ()
#4 0x0000000111ea38cd in (anonymous namespace)::AutoreleasePoolPage::pop(void*) ()
#5 0x00000001124a9f06 in _CFAutoreleasePoolPop ()
#6 0x000000010fda487a in -[__NSOperationInternal _start:] ()
#7 0x000000010fda4383 in __NSOQSchedule_f ()
#8 0x0000000112acb614 in _dispatch_client_callout ()
#9 0x0000000112ab26a7 in _dispatch_queue_drain ()
#10 0x0000000112ab1cc0 in _dispatch_queue_invoke ()
#11 0x0000000112ab53b9 in _dispatch_root_queue_drain ()
#12 0x0000000112ab6b17 in _dispatch_worker_thread3 ()
#13 0x0000000112e394f2 in _pthread_wqthread ()
#14 0x0000000112e37375 in start_wqthread ()
Enqueued from com.apple.main-thread (Thread 1)Queue : com.apple.main-thread (serial)
#0 0x0000000112aaf43f in _dispatch_barrier_async_f ()
#1 0x000000010fda422a in __NSOQSchedule ()
#2 0x000000010fda3911 in __addOperations ()
#3 0x000000010ec03828 in -[TTObjectRequestManager addMapOperationForData:success:failure:] at /Users/ian/Code/tt/bowtie/Pods/Tophat-iOS/Classes/Services/Library/TTObjectRequestManager.m:140


However, unlike other instances of this assertion, the stack trace does not include any frames from the NSOperation itself, leading me to suspect this is an internal issue.

From looking at the trace, it looks like you are truly accessing the MOC inappropriately. However, I could be missing something. What's the code for that NSOperation?

I don't believe so, given that the assertion only fires with Xcode 7 and 8.4. All other combinations of Xcode/iOS are fine, and have been fine for many months.


I have read it over and over many times, I'm unable to spot any issues. I've fixed many Core Data bugs, and we have a well established approach for correctly handling our contexts. This NSOperation has also been reviewed by Marcus Zarra (Core Data book author).


I can probably arrange for an Apple engineer to have access to the code, but I can't post it publically (not my decission to make, sorry!).

any update on this? I've updated to XCode 7.1 and still experiencing this issue. Code runs fine when running on devices with 7.1 and 9.0+, but I get this assertion on iOS 8.4. With XCode 6.4, code runs with no issues in iOS 7,8 and 9.

No update. It's odd that you're seeing the assertion in Xcode 6.4 & iOS 8.4, but not using Xcode 7.1 and iOS 8.4. That's the inverse of what others have observed in this thread.

Any solutions? I likewise am seeing this issue and I suspect strongly it's the source of crashes/odd behaviour in my app that I'm only seeing on iOS 8.4 and not on 9.x.


I've been very careful with my core data stack - I only create 2 managed object contexts, a main queue context and a private queue context. The odd behaviour I'm seeing with the private queue context, but I always defer work via performBlock or performBlockAndWait. The problem seems to only occur when the work is enqueued from another background thread (e.g. data returned from a network operation, then processed on the context's queue). I do not get *any* threading violations triggered on iOS 9.x, only on an 8.4 device I'm using for testing.

I've reduced the code that causes the threading violation error down to something just like this (names of entities changed to protect client's interests):


class Folder: NSManagedObject {
  static let entityName = "Folder"
}

class Something: NSManagedObject {
    static let entityName = "Something"

    @NSManaged var folder: Folder
    @NSManaged var uid: Int64

    static func findSomethingInFolder(folder: Folder, withUid uid: Int64, inContext context: NSManagedObjectContext) -> Something? {
        var something: Something?
        context.performBlockAndWait {
            let folder = try! context.existingObjectWithID(folder.objectID) as! Folder
            let predicate = NSPredicate(format: "(uid == %@) AND (folder == %@)",
                NSNumber(longLong: uid), folder)
            let request = NSFetchRequest(entityName: entityName)
            request.predicate = predicate
            request.returnsObjectsAsFaults = false
            request.fetchLimit = 1
            let results = try! context.executeFetchRequest(request)
            let somethings = results as! [Something]
            let something = somethingss.first
        }
        return something
    }
}


When this code is executed with CoreData concurrency checking enabled, it stops with a multithreading violation on the line "let results = try! context.executeFetchRequest(request)", but only on iOS 8.4 (simulator & device), built with Xcode 7.1.1.

I think you misread. grd888 is saying that he gets the issue with Xcode 7.1/iOS 8.4, but not with Xcode 6.4 on any iOS version.

I've found no solution and there has been no activity on the bug report either.

I'm experiencing this issue as well in one of my projects. Lost about half a day on it before discovering this thread 👿