CoreMotion crash(iPad-only) on invoking stopDeviceMotionUpdates - ios

We have an instance of CMMotionManager in our app which we use to get sensor updates at a frequency of 5Hz. Following is the code we use to start motion updates:
[self.motionManager
startDeviceMotionUpdatesUsingReferenceFrame:
CMAttitudeReferenceFrameXMagneticNorthZVertical
toQueue:operationQueue
withHandler:^(CMDeviceMotion *motion, NSError *error) {
if (!error) {
[self doSomethingWithMotion:motion];
} else { ... }
The above method is always invoked on the main thread.
Now, once we are done with our task, we stop motion updates by calling the following method, again on the main thread :
- (void)stopMotionUpdates {
// This might get called on concurrent threads.
// So better using sync block + make it idempotent
#synchronized(self) {
if (_motionManager.deviceMotionActive) {
[_motionManager stopDeviceMotionUpdates];
_prevPoint = nil;
}
}
}
The issue we are facing is that the stopMotionUpdates crashes, that too, only in iPads. We have tested this extensively on iPhones and iPads with different OS versions and we get the crash only on iPads (mini 1,2 and retina/non-retina) for both iOS7 and iOS8. Also, we cannot reproduce the crash on all iPads which we use for testing, but only a few. Following are the crash logs for main and the crashed thread:
Thread : com.apple.main-thread
0 libsystem_kernel.dylib 0x00000001935f1cdc semaphore_wait_trap + 8
1 libdispatch.dylib 0x00000001934fbb3c _dispatch_semaphore_wait_slow + 252
2 CoreMotion 0x0000000186bf67d4 (null)
3 CoreMotion 0x0000000186be3698 (null)
4 MyApp 0x00000001002f7434 -[MyAppMotionManager stopMotionUpdates]
...
...
12 MyApp 0x00000001002e94f8 __getDispatchTimer_block_invoke
13 libdispatch.dylib 0x00000001934f3fd4 _dispatch_client_callout + 16
14 libdispatch.dylib 0x00000001934f5b90 _dispatch_source_invoke + 500
15 libdispatch.dylib 0x00000001934f7180 _dispatch_main_queue_callback_4CF + 244
16 CoreFoundation 0x00000001864fec2c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
17 CoreFoundation 0x00000001864fcf6c __CFRunLoopRun + 1452
18 CoreFoundation 0x000000018643dc20 CFRunLoopRunSpecific + 452
19 GraphicsServices 0x000000018c0ddc0c GSEventRunModal + 168
20 UIKit 0x000000018956efdc UIApplicationMain + 1156
21 MyApp 0x00000001000c9850 main (main.m:14)
22 libdyld.dylib 0x000000019350faa0 start + 4
EXC_BREAKPOINT UNKNOWN at 0x0000000186c257ac
Thread : Crashed: Thread
0 CoreMotion 0x0000000186c257ac (null) + 110504
1 CoreMotion 0x0000000186c25774 (null) + 110448
2 CoreMotion 0x0000000186bf3c84 (null)
3 CoreMotion 0x0000000186bf67ec (null)
4 CoreMotion 0x0000000186bf3b80 (null)
5 CoreMotion 0x0000000186c24c48 (null) + 107588
6 CoreMotion 0x0000000186bf67ec (null)
7 CoreMotion 0x0000000186c24ba4 (null) + 107424
8 CoreMotion 0x0000000186be3b9c (null)
9 CoreMotion 0x0000000186bf6860 (null)
10 CoreFoundation 0x00000001864ff680 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20
11 CoreFoundation 0x00000001864fe838 __CFRunLoopDoBlocks + 300
12 CoreFoundation 0x00000001864fd0a4 __CFRunLoopRun + 1764
13 CoreFoundation 0x000000018643dc20 CFRunLoopRunSpecific + 452
14 CoreFoundation 0x00000001864932a8 CFRunLoopRun + 112
15 CoreMotion 0x0000000186bf653c (null)
16 libsystem_pthread.dylib 0x000000019368be1c _pthread_body + 168
17 libsystem_pthread.dylib 0x000000019368bd74 _pthread_body
Since we reference self in the motion update handler block, the object shouldn't be deallocated till the entire queue is flushed. Any help is appreciated :)

You might be overloading the main thread.
As a rule of thumb, you should never do anything on the main thread that takes more than or about a second.
The main thread is responsible for running the user interface. If you block the main thread for any significant amount of time, the user interface becomes unacceptably unresponsive.
watchdog — In order to keep the user interface responsive, iOS includes a watchdog mechanism. If your application fails to respond to certain user interface events (launch, suspend, resume, terminate) in time or some operation takes little bit more time on the main thread then the watchdog will kill your application. The amount of time the watchdog gives you is not formally documented, but it's always less.
Any such operation must be done on a background thread and you could easily do it using
dispatch_async
NSOperationQueue
performSelectorInBackground
Hope this helps.

Your crash comes from the #synchronized directive. As you can see the main thread is executing your code in #synchronized. This locks the view controller, from being accessed by any other thread.
The thread that is crashed is for the CoreMotion and I suppose it was trying to give updates on the device motion.
I believe the crash is happening just in some cases when the CoreMotion happens to try to updates in the same time your main thread runs through synchronized.

Where do you define 'operationQueue' there's no self so I'm assuming it's not a class level variable. You want that to be a class property with a strong reference so it isn't deallocated while receiving updates. I've also seen this happen with function scoped variables for the dispatch_queue_t on bluetooth calls.
Memory management would explain the erratic behavior, but you could always try to make iOS more aggressive by opening other apps & a bunch of website tabs on the iPads you've seen this issue on before.
CMMotion updates have got to work in a FIFO order to be accurate so that could explain why you see semaphore_wait_trap in the logs.

Related

How to find root cause Crashed: com.apple.main-thread in production app?

i have such a report from Crashlytics:
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x000000019503fbd0 objc_msgSend + 16
1 CoreFoundation 0x00000001836e5458 CFRelease + 524
2 CoreFoundation 0x00000001836f1a18 -[__NSArrayM dealloc] + 152
3 libobjc.A.dylib 0x0000000195045724 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 564
4 CoreFoundation 0x00000001836e9074 _CFAutoreleasePoolPop + 28
5 Foundation 0x000000018461a588 -[NSAutoreleasePool release] + 148
6 UIKit 0x00000001882b4460 -[UIApplication _run] + 588
7 UIKit 0x00000001882aefac UIApplicationMain + 1488
Is there anything I can do to catch such an issue? It happens on customer devices so I have no chance to reproduce it.
For crashes like this one, if the crash is reproducible, turn on NSZombies in your project's environment variables. This will keep deallocated objects alive (zombies) and when one of them is messaged, the caller and message will be captured on the crashing object.
Turn it off when done as it can block the memory of the app due to the objects not being released for zombie tracking.
Some of logic code need to be run in background. You need to try debug where is code is error and then add this code
DispatchQueue.main.async(execute: {
// your code
})
It's been answered here: objc_msgSend [__NSArrayM dealloc] crash report sometimes from Crashlytics
Basically, upgrade your Crashlytics framework to past 3.0.9. The crash was in the crash reporting framework itself.

weird crash when launching app from Notification Center

I'm at my wits end, I'm getting a weird crash that only happens when the app is launched from Notification Center. Either tapping on a local notification (in the notification side) or a call to extensionContext:openURL:completionHandler (from my Today widget) will launch the app with a customURL scheme.
When the app is running (warm boot), no issues, works just as advertised. When I kill the app (in task switcher) and then try to launch it through Notification Center (cold boot), I get the below crash report.
I've search low and high for anything, can't find it. This only happens on iOS8 devices, iOS7 devices has no issue (with the notification launch, obviously no Today widget)
Has anyone seen this??
thanks!
Date/Time: 2014-10-14 18:16:39.924 -0400
Launch Time: 2014-10-14 18:16:38.667 -0400
OS Version: iOS 8.0.2 (12A405)
Report Version: 105
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x000000016a4cbeb8
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x0000000195ebbbd0 objc_msgSend + 16
1 UIKit 0x000000018a27d840 -[UIApplication workspaceDidEndTransaction:] + 216
2 FrontBoardServices 0x000000018da7563c __31-[FBSSerialQueue performAsync:]_block_invoke + 24
3 CoreFoundation 0x000000018582a35c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 16
4 CoreFoundation 0x0000000185829464 __CFRunLoopDoBlocks + 308
5 CoreFoundation 0x0000000185827a88 __CFRunLoopRun + 1752
6 CoreFoundation 0x0000000185755660 CFRunLoopRunSpecific + 392
7 UIKit 0x000000018a05f4fc -[UIApplication _run] + 548
8 UIKit 0x000000018a05a4f4 UIApplicationMain + 1484
9 therichest 0x00000001001caa8c main (main.m:16)
10 libdyld.dylib 0x0000000196516a04 start + 0
Either your code or a third-party library you are using is manually spinning the runloop. This is causing -workspaceDidEndTransaction: to be called re-entrantly and triggers a use after free. If you set a breakpoint on -[NSRunLoop runMode:beforeDate:] and -[NSRunLoop runUntilDate:], it should hit with the guilty code being on the previous stack frame.
While manually spinning the run loop is never recommended, if you can delay doing it until your application finishes starting up (all the launch app delegate calls received) you should avoid hitting this crash.

AFNetworking crash analysis for EXC_BAD_ACCESS KERN_INVALID_ADDRESS

I'm getting crash reports of AFNetworking throwing an EXC_BAD_ACCESS KERN_INVALID_ADDRESS:
Thread : Crashed: com.apple.root.default-priority
0 libobjc.A.dylib 0x39e237fa objc_release + 9
1 MY_APP 0x0015ba63 __64-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke (AFHTTPRequestOperation.m:266)
2 MY_APP 0x00163bf7 __47-[AFURLConnectionOperation setCompletionBlock:]_block_invoke (AFURLConnectionOperation.m:301)
3 Foundation 0x3049a2a9 __103+[__NSOperationInternal _observeValueForKeyPath:ofObject:changeKind:oldValue:newValue:indexes:context:]_block_invoke96 + 12
4 libdispatch.dylib 0x3a30b0c3 _dispatch_call_block_and_release + 10
5 libdispatch.dylib 0x3a3107d9 _dispatch_root_queue_drain + 224
6 libdispatch.dylib 0x3a3109c5 _dispatch_worker_thread2 + 56
7 libsystem_pthread.dylib 0x3a43adff _pthread_wqthread + 298
I need help to understand the possible bug. This is something that happens sometimes, actually is very rare and it could be related to a timeout issue when user is using 3G (network can be disconnected while loading data).
I don't post my code because I can't find on the crash log in which file or class this crash happened and I use AFNetworking in a lot of files.
Without any code this is all conjecture but:
Something in the completion block is being accessed after it is deallocated. Commonly, this happens when a network operation isn't cancelled after a view controller is dismissed.

Does anyone know whats going on here ? Core Data / iCloud

So whats happening here is the app has just received the NSPersistentStoreDidImportUbiquitousContentChangesNotification, and I have just called
- (void)storesDidUpdate:(NSNotification*)note {
FLOG(#"storesDidUpdate ");
[_managedObjectContext mergeChangesFromContextDidSaveNotification:note];
// Refresh user Interface
[[NSNotificationCenter defaultCenter] postNotificationName:#"iProjectCoreDataUpdated"
object:self];
[self updateDetails];
}
And now the app is trying to update a UITextView with a fresh copy of text by simply doing the following:
self.detailText.attributedText = [self.detailItem valueForKey:#"scope"];
Where detailItem is a NSManagedObject retrieved prior to receiving the update from iCloud.
Not sure why the textContainer is complaining or what its complaining about, and also not sure why importing logs is happening because I have already received a notification that its done!
Strangely other UITableViews update correctly if I just call reloadData.
Any ideas on whether I am doing something wrong here? Note that if I don't try and update the textView it works fine and if I close the view and go back to it then I get the correct data.
Also when I restart the app all the data is there, no corruptions or anything, in fact the app seems remarkably robust in most respects when it comes to the Core Data store, despite things blowing up on either side of iCloud!
Oh and the reloadFetchedResults is a bit misleading because I don't seem to need to do that, so the method name is a hangover from the past, all I am doing is refreshing values in the UI in this call.
2013-10-09 07:25:53.783 MyApp[4509:510b] OpeningViewController.reloadFetchedResults: called
2013-10-09 07:25:53.786 MyApp[4509:510b] InfoDetailViewController.reloadFetchedResults: called in InfoDetailViewController
2013-10-09 07:25:53.788 MyApp[4509:510b] * Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *, UIView *, NSTextContainer *, NSUInteger)(), /SourceCache/UIFoundation/UIFoundation-258/UIFoundation/TextSystem/NSLayoutManager_Private.m:1510
2013-10-09 07:25:53.793 MyApp[4509:510b] -_PFUbiquityRecordImportOperation main: CoreData: Ubiquity: Error importing transaction log:
transactionLogLocation: : /var/mobile/Library/Mobile Documents/HHHHHHNNNN~com~mycompany~MyApp/CoreData/New Document/duncangroenewald~simAABC628E-9D5E-58F7-9B8D-0BC724C6D0C8/New Document/W8MckEJ0x2d~HZZIeUH2be6hs41TEOONzKIrCuLcuP4=/6C953E7C-B2AF-47F7-B828-DD062B96415D.1.cdt
transactionNumber: 5
, exception: Only run on the main thread!
User Info: (null)
2013-10-09 07:25:53.803 MyApp[4509:510b] -_PFUbiquityRecordsImporter operation:failedWithError:: CoreData: Ubiquity: Import operation encountered an error: Error Domain=NSCocoaErrorDomain Code=134060 "The operation couldn’t be completed. (Cocoa error 134060.)" UserInfo=0x16d882c0 {exception=Only run on the main thread!}
userInfo: {
exception = "Only run on the main thread!";
}. While trying to import the log file at the URL:
transactionLogLocation: : /var/mobile/Library/Mobile Documents/HHHHHHNNNN~com~mycompany~MyApp/CoreData/New Document/duncangroenewald~simAABC628E-9D5E-58F7-9B8D-0BC724C6D0C8/New Document/W8MckEJ0x2d~HZZIeUH2be6hs41TEOONzKIrCuLcuP4=/6C953E7C-B2AF-47F7-B828-DD062B96415D.1.cdt
transactionNumber: 5
2013-10-09 07:25:53.809 MyApp[4509:510b] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!'
*** First throw call stack:
(0x2ff23f53 0x3a6996af 0x2ff23e2d 0x308cb1df 0x3796643d 0x37966185 0x3798f7bb 0x379926f7 0x37992759 0x379b378b 0x379b331f 0x379b2f0d 0x3273b05d 0x129717 0x2fee6121 0x2fe5a317 0x3083edcd 0x308436ab 0x118263 0x2fee6121 0x2fe5a317 0x2fd8c69f 0x2fd8cc93 0x2fd813dd 0x3085197b 0x308f5b35 0x3ab83297 0x3ab8309b 0x3ab83d15 0x3ab83f8d 0x3acbedbf 0x3acbec84)
libc++abi.dylib: terminating with uncaught exception of type NSException
EDIT:
I have posted some sample Core Data/iCloud apps for iOS and OSX here - they include background threads for loading/deleting data as well as iCloud sync. Hopefully address the issue described here. http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/
OK here is what seems to fix it - I guess I never realised that receiving a notification would run on another thread. Is that normal behaviour, are all Core Data notifications you receive called on a background thread ? If so do you always have to make sure anything you do is then running on the correct thread ?
- (void)storesDidUpdate:(NSNotification*)note {
FLOG(#"storesDidUpdate ");
[_managedObjectContext mergeChangesFromContextDidSaveNotification:note];
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
//Your code goes in here
LOG(#" Main Thread Code");
// Refresh user Interface
[[NSNotificationCenter defaultCenter] postNotificationName:#"CoreDataUpdatedNotification"
object:self];
}];
}
EDIT:
I have finally gotten around to documenting how I got Core Data and iCloud to work pretty reliably, including handling moving to and from iCloud in response to the use changing their Use iCloud preference settings. I was unable to find a good explanation with working code when I was trying to figure out how to get it working so I hope this proves useful to others. Included is a video of the app working so you can see how it behaves to help you figure out if it's what you are wanting to achieve.
http://ossh.com.au/design-and-technology/software-development/
I got the same problem. It was exactly the issue #John Rogers explained.
I created UITextViews and in the background I called a URL to get some data which should be inserted into my generated UITextViews. But the Problem was the method sendAsynchronousRequest which will be called in background and cause the crash in my case.
I could solve the problem by performing the specific selector on main thread when receiving my data. So maybe you can insert you're method call into another method and call it this way:
[self performSelectorOnMainThread:#selector(received:)
withObject:data
waitUntilDone:YES];
This way you get back to the main thread again.
Reading all the answers+comments (and your fix) - I think it should be noted you MUST update any UI control from the main thread only.
I assume the [self updateDetails]; calls the self.detailText.attributedText = [self.detailItem valueForKey:#"scope"]; code?...which is the actual code that updates the UI?
Assume that, then You could execute the call to -updateDetails using -performSelectorOnMainThread: or in the -updateDetails check that you are executing on the main thread ([NSThread isMainThread]) and wrap the UI update code there so the caller doesn't care what thread they call -updateDetails from.
Yes, I get that but I don't do anything on any threads so something else must be. I am updating a UITextView and I guess its possible something in that is causing a failure. I am not clear on why this would have anything to do with the ubiquityImporter - perhaps someone who can interpret this stuff below can point me in the right direction. Am I somehow running something on the wrong thread ?
First throw call stack:
(
0 CoreFoundation 0x027c55e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x019238b6 objc_exception_throw + 44
2 CoreFoundation 0x027c5448 +[NSException raise:format:arguments:] + 136
3 Foundation 0x01062960 -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 101
4 UIFoundation 0x01b33131 -[NSLayoutManager(NSPrivate) _resizeTextViewForTextContainer:] + 419
5 UIFoundation 0x01b32e16 -[NSLayoutManager(NSPrivate) _recalculateUsageForTextContainerAtIndex:] + 2083
6 UIFoundation 0x01b67675 _enableTextViewResizing + 234
7 UIFoundation 0x01b6b275 -[NSLayoutManager textStorage:edited:range:changeInLength:invalidatedRange:] + 688
8 UIFoundation 0x01b6b2fa -[NSLayoutManager processEditingForTextStorage:edited:range:changeInLength:invalidatedRange:] + 82
9 UIFoundation 0x01b93d35 -[NSTextStorage _notifyEdited:range:changeInLength:invalidatedRange:] + 153
10 UIFoundation 0x01b93870 -[NSTextStorage processEditing] + 462
11 UIFoundation 0x01b93419 -[NSTextStorage endEditing] + 80
12 UIFoundation 0x01b934a3 -[NSTextStorage coordinateEditing:] + 66
13 UIKit 0x007f4f48 -[UITextView setAttributedText:] + 254
14 MyApp 0x00027d7a -[WBSDetailViewController displayItem] + 3146
15 MyApp 0x00028c6c -[WBSDetailViewController refreshUI:] + 156
16 Foundation 0x01088e39 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40
17 CoreFoundation 0x02821524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
18 CoreFoundation 0x0277907b _CFXNotificationPost + 2859
19 Foundation 0x00fc2b91 -[NSNotificationCenter postNotificationName:object:userInfo:] + 98
20 Foundation 0x00fd206a -[NSNotificationCenter postNotificationName:object:] + 55
21 MyApp 0x00031095 -[BaseAppDelegate storesDidUpdate:] + 293
22 Foundation 0x01088e39 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40
23 CoreFoundation 0x02821524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
24 CoreFoundation 0x0277907b _CFXNotificationPost + 2859
25 Foundation 0x00fddd7b -[NSNotificationCenter postNotification:] + 121
26 CoreData 0x0173c5f4 -[_PFUbiquityRecordsImporter postImportNotificationForStoreName:andLocalPeerID:withUserInfo:] + 1892
27 CoreData 0x0173cbc2 -[_PFUbiquityRecordsImporter operationDidFinish:] + 706
28 CoreData 0x0172e8ce -[_PFUbiquityRecordImportOperation main] + 15102
29 Foundation 0x0108aa69 -[__NSOperationInternal _start:] + 671
30 Foundation 0x01007798 -[NSOperation start] + 83
31 Foundation 0x0108cd34 __NSOQSchedule_f + 62
32 libdispatch.dylib 0x05b794b0 _dispatch_client_callout + 14
33 libdispatch.dylib 0x05b67088 _dispatch_queue_drain + 450
34 libdispatch.dylib 0x05b66e85 _dispatch_queue_invoke + 126
35 libdispatch.dylib 0x05b67e25 _dispatch_root_queue_drain + 83
36 libdispatch.dylib 0x05b6813d _dispatch_worker_thread2 + 39
37 libsystem_pthread.dylib 0x05f05dab _pthread_wqthread + 336
38 libsystem_pthread.dylib 0x05f09cce start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Crash on __dispatch_call_block_and_release

I have an iOS app, and I am getting quite amount of this crash.
And it seems that it is not related to my code. Do you have any idea why the app can crash because of this. Is there something that I can do to prevent these crashes.
Thread 9 Crashed:
1 libobjc.A.dylib _objc_msgSend + 16
2 libdispatch.dylib __dispatch_call_block_and_release + 13
3 libdispatch.dylib __dispatch_queue_drain + 239
4 libdispatch.dylib __dispatch_queue_invoke$VARIANT$mp + 41
5 libdispatch.dylib __dispatch_worker_thread2 + 211
6 libsystem_c.dylib __pthread_wqthread + 295
GCD is used in your app. So..
Bring more detail-info please? code where it's occurred?
May be you need copy block vs retain, may be you need use __block vars correctly. May be something else. Obviously, your object had been captured by block is released and deallocated when happens queue_drain, and after that you call method of the object in other scope, or in the block scope.

Resources