Stickers for OSSpinLockLockSlow

Update 2: I found a workaround which is to synchronize the freeing and saving of MOC. See Updated Project. https://github.com/shuningzhou/MOCDeadLock.git

Note. I made it more aggressive. Do not run it on a real device!

Update: A sample project to demonstrate this problem. https://github.com/shuningzhou/MOCDeadLock.git

Xcode 6.2: Unable to play.

Xcode 6.3: Playable.

Xcode 6.4 beta: Reproducibility.

========================== Problem ========================= =======

Our application accidentally got stuck on OSSpinLockLockSlow after upgrading to Xcode 6.3. In our project, we used NSOperation and NSOperationQueue to retrieve data from our server and use Core Data to save data.

This question has never happened before! From the stack trace, you can see that our codes are not ringing. I don’t know where to start this debugging. Can someone give some recommendations?

Thank you in advance!

Please view stack trace enter image description here

enter image description here

Edit:

We use AFNetworking , and our NSOperations are subclasses of AFHTTPRequestOperation . We added some custom properties and redefined the -(void)start method:

 - (void)start; { //unrelated code... NSString *completionQueueID = [NSString uuid]; const char *cString = [completionQueueID cStringUsingEncoding:NSASCIIStringEncoding]; self.completionQueue = dispatch_queue_create(cString, DISPATCH_QUEUE_SERIAL); //unrelated code.... [super start]; } 

For Core Data , we follow the thread-confinement pattern. We have a separate managed object context for each thread, and contexts have a static persistent store coordinator .

Edit 2:

Additional Information: I found that this problem occurs when the system exits from multiple threads simultaneously. We store the managed entity context in the thread dictionary, and they are freed when the threads exit.

 [[[NSThread currentThread] threadDictionary] setObject:dataManager forKey:@"IHDataManager"]; 

CPU usage is about 20%. enter image description hereenter image description here

+10
ios nsoperation
May 15, '15 at 21:46
source share
2 answers

I faced exactly this problem. According to your stack trace, I have a bunch of threads stopped using _OSSpinLockLockSlow.

It seems that this is the situation with a zipper, when the spinning brackets are connected by chains. Including some network streams and master data. But, as Rob noted, the symptoms of livelock should include high processor loads (all the studs all rotate endlessly). In my case (and in yours) this is not so, the processor usage is low - the “percent used” simulator is 20%, the simulator as a whole on the activity monitor is 0.6% - so this may be a dead end; -)

Like you, I use a flow restriction pattern, a separate managed object context for the flow, one persistent storage.

After you noticed that the hang always seems to follow the cancellation of the thread bundle, I checked this behavior and can confirm that it is.

I wondered why I have so many threads. It turned out that I am using gcd with a parallel background queue:

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0),^{ modelClass = [WNManagedObject classForID:mongoID]; dispatch_async(dispatch_get_main_queue(),^{ ... }); }); 

This snippet is part of some network / JSON parsing code. "classForID" caused small fluctuations in the user interface in the main thread, so I used it.

In fact, the parallel background queue spit out a whole bunch of short-lived threads. It was completely unnecessary. Refactoring as a single sequential queue fixed surplus threads that got rid of the spinlock problem. Finally, I realized that I don’t need to get a class at all, so this code has since been exiled.

The problem is fixed, but there is no explanation why this should suddenly become a problem with 8.3

I suspect the same issue is being addressed in this issue (although Cocoalumberjack gets the blame there):
Syscall_thread_switch iOS 8.3 race - CocoaLumberjack bug? how to debug this?

.. and in this Cocoalumberjack bug report
https://github.com/CocoaLumberjack/CocoaLumberjack/issues/494

I also use CocoaLumberjack, but it does not work in any of the problematic threads, so I think this is a red herring. The main reason, apparently, is to create redundant threads.

I saw a problem in the simulator and on devices bound to Xcode, but I did not experience this when working independently of Xcode. This is new to iOS 8.3 / Xcode 6.3.1

This is actually not the answer, more the diary of my workaround for this strange problem, but you might find it useful.

+13
May 19 '15 at 18:18
source share
— -

If the question is still relevant - this is a bug in iOS: OpenRadar crash report
You may also find this blog post helpful: blog post

I think you should replace OSSpinLocks with something else to fix this in your application.

We encountered this error in our Unity3d game. We have not yet fixed this in our application, because we do not have access to most native iOS codes (we write our game in C # and we use many plugins for native 3-party developers). Therefore, I cannot recommend you anything specific regarding replacing OSSpinLock. Sorry for my English.

Update
Many Apple frameworks and libraries use OSSpinLock internally, so you don't need to use it to accomplish this problem.

+1
Jan 26 '16 at 9:53 on
source share



All Articles