I get the following crash:
Exception Type: 00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread: 0
Application Specific Information:
com.[app name].[app name] failed to scene-update in time
Elapsed total CPU time (seconds): 5.050 (user 5.050, system 0.000), 24% CPU
Elapsed application CPU time (seconds): 0.044, 0% CPU
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x0000000195018e48 semaphore_wait_trap + 8
1 libdispatch.dylib 0x0000000194efbf3c _dispatch_semaphore_wait_slow + 252
2 CFNetwork 0x00000001832a2220 CFURLConnectionSendSynchronousRequest + 284
3 CFNetwork 0x00000001832c27c8 +[NSURLConnection sendSynchronousRequest:returningResponse:error:] + 116
4 Foundation 0x0000000184726358 -[NSData(NSData) initWithContentsOfURL:options:error:] + 308
5 Foundation 0x0000000184726204 +[NSData(NSData) dataWithContentsOfURL:options:error:] + 72
6 [app name] 0x00000001000b1a30 0x100090000 + 137776
7 [app name] 0x00000001001e3f44 0x100090000 + 1392452
8 libdispatch.dylib 0x0000000194eed990 _dispatch_call_block_and_release + 20
9 libdispatch.dylib 0x0000000194eed950 _dispatch_client_callout + 12
10 libdispatch.dylib 0x0000000194ef2208 _dispatch_main_queue_callback_4CF + 1604
11 CoreFoundation 0x00000001838962e8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
12 CoreFoundation 0x0000000183894390 __CFRunLoopRun + 1488
13 CoreFoundation 0x00000001837c11f0 CFRunLoopRunSpecific + 392
14 GraphicsServices 0x000000018cae36f8 GSEventRunModal + 164
15 UIKit 0x0000000188152108 UIApplicationMain + 1484
16 [app name] 0x00000001000dd2ac 0x100090000 + 316076
17 libdyld.dylib 0x0000000194f1aa04 start + 0
On the following code:
#try {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^(void) {
NSData* data = [NSData dataWithContentsOfURL:xxxxxxx options:NSDataReadingUncached error:&error];
...
[self.buffer performSelectorOnMainThread:#selector(addObject:) withObject:data waitUntilDone:YES];
}
#catch (NSException* error) {
NSLog(#"error: %#", error);
}
Yes there is a failure block too, but I simplified the code to the essence, the pure code that causes the crash.
This code runs hundreds of times per hour without any problem. But every now and then it crashes. Always the same crash (like the one above). First, the app freezes, then it crashes. The catch-block is never executed.
The performSelectorOnMainThread uses an object. And that object is added (in the main thread) to an NSMutableArray (self.buffer is an NSMutableArray). I know that NSMutableArrays are not thread-safe and that's why I perform them on the main thread. For waitUntilDone I use YES to prevent the thread from ending before the object is inserted. I used NO too, but that crashes constantly.
Does anyone have an idea why this crash happens? And do you perhaps have a solution for me to prevent this?
Thanks a lot.
You are doing network i/o on the main thread while updating the UI. This takes too long. Don't do that on the main thread. Instead, use an asynchronous way to run the URL fetch and cache the result so it can be used by the next user interface update.
More information:
https://developer.apple.com/library/ios/qa/qa1693/_index.html
Writing to the array on the main thread does not make it thread safe. Use a dedicated dispatch_queue to control access to the nsmutablearray instead, both read and write operations.
https://stackoverflow.com/a/4607664/573988
Related
I use crashlytics to get the crashes of my app, i am currently Crashlytics version: 3.9.3. Some users are getting a crash that I cannot seem to repro on my machine. This is the logs from Fabric:
Crashed: com.apple.root.default-qos
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x00004a4b9a43bec8
#37. Crashed: com.apple.root.default-qos
0 libobjc.A.dylib 0x7fff6b43d184 objc_release + 36
1 MyApp 0x10805ad2d __66-[AppManager getCountriesDelegate:]_block_invoke (AppManager.m:1412)
2 libdispatch.dylib 0x7fff6c006591 _dispatch_call_block_and_release + 12
3 libdispatch.dylib 0x7fff6bffed50 _dispatch_client_callout + 8
4 libdispatch.dylib 0x7fff6c00bc61 _dispatch_queue_override_invoke + 880
5 libdispatch.dylib 0x7fff6c000941 _dispatch_root_queue_drain + 515
6 libdispatch.dylib 0x7fff6c0006ed _dispatch_worker_thread3 + 101
7 libsystem_pthread.dylib 0x7fff6c2c31ca _pthread_wqthread + 1387
8 libsystem_pthread.dylib 0x7fff6c2c2c4d start_wqthread + 13
- (void) getCountriesDelegate:(id<AppManagerDelegate>)delegate
{
__weak __typeof(id<AppManagerDelegate>) weakDelegate = delegate;
__weak __typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //my function definition
});
There are multiples reasons why you can get a EXC_BAD_ACCESS KERN_INVALID_ADDRESS error code. Appel's documentation says:
EXC_BAD_ACCESS/KERN_INVALID_ADDRESS — This is caused by the thread
accessing unmapped memory. It may be triggered by either a data access
or an instruction fetch; the Thread State section describes how to
tell the difference.
You should look deeply at your class AppManager. As the crashlog said's the crash occurs at line 1412 of file AppManager.m in the method getCountriesWithRespectToPurposeAndFavoriteDelegate:.
I apologize in advance that this probably won't end up contributing much to the general knowledge base here, but I'm looking for help diagnosing what's likely a configuration oversight that's causing my unit tests to crash sporadically.
I'm set up using RestKit with an in-memory object store while unit testing, so that after each test case, I can reset my persistent stores and each test can run with a fresh database. Much of the time my test suite runs without issue, but often enough to be a deal-breaker, there's a crash from what [I think] appears to be over-releasing a managed object context. All relevant code and crash data below:
Unit Test Base Class Setup
#implementation MyTestCase
- (void)setUp
{
[super setUp];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[MyObjectManager sharedManager] start];
});
}
- (void)tearDown
{
[super tearDown];
[[MyObjectManager sharedManager] reset];
}
Relevant MyObjectManager Setup
#interface MyObjectManager : RKObjectManager
- (void)start
{
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithPersistentStoreCoordinator:[self persistentStoreCoordinator]];
self.managedObjectStore = managedObjectStore;
[managedObjectStore createManagedObjectContexts];
[RKManagedObjectStore setDefaultStore:managedObjectStore];
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
{
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:kRDPersistentStore];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = #{
NSSQLitePragmasOption : #{
#"synchronous" : #"FULL",
#"fullfsync" : #(1)
},
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES
};
NSError *error = nil;
if (![self persistentStoreAtPath:storeURL options:options error:error])
{
NSLog(#"Error adding store %#: %#, %#", storeURL, error, [error userInfo]);
// Additional handling
}
return _persistentStoreCoordinator;
}
- (NSPersistentStore *)persistentStoreAtPath:(NSURL *)storeURL options:(NSDictionary *)options error:(NSError *)error
{
// (NSSQLiteStoreType and storeUrl are used if we're not unit testing)
return [_persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil
URL:nil
options:options
error:&error];
}
MyObjectManager::reset Implementation
- (void)reset
{
[[RKObjectManager sharedManager].operationQueue cancelAllOperations];
NSError *error = nil;
[[RKManagedObjectStore defaultStore] resetPersistentStores:&error];
if (error)
{
NSLog(#"Error! : %#", error);
}
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
Typical Crash Report
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGSEGV)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
iPhone Simulator 463.9.41, iPhone OS 7.1 (iPhone Retina (4-inch)/11D167)
Main thread is spinning the run loop, waiting on an asynchronous test case:
(Not always the case but a majority of our tests employ this method)
Thread : com.apple.main-thread
0 libsystem_kernel.dylib 0x047f6f92 semaphore_signal_trap + 10
1 libdispatch.dylib 0x0447f41f _dispatch_barrier_sync_f_slow_invoke + 54
2 libdispatch.dylib 0x044904d0 _dispatch_client_callout + 14
3 libdispatch.dylib 0x0447e726 _dispatch_main_queue_callback_4CF + 340
4 CoreFoundation 0x040fb43e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
5 CoreFoundation 0x0403c5cb __CFRunLoopRun + 1963
6 CoreFoundation 0x0403b9d3 CFRunLoopRunSpecific + 467
7 CoreFoundation 0x0403b7eb CFRunLoopRunInMode + 123
8 Foundation 0x03a71e35 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 284
9 Foundation 0x03a71cd5 -[NSRunLoop(NSRunLoop) runUntilDate:] + 88
10 Remind101-Tests 0x0cbb2c02 -[UTTestCase waitForBlockWithTimeout:] + 233
11 Remind101-Tests 0x0cbb2b14 -[UTTestCase waitForBlock] + 49
12 Remind101-Tests 0x0cbba55e -[UTAPITestCase sendRequestExpectingSuccess:] + 142
13 Remind101-Tests 0x0cb92832 -[UTMessageRequestTests testRequestCreatesFileEntities] + 166
14 CoreFoundation 0x0408a91d __invoking___ + 29
15 CoreFoundation 0x0408a82a -[NSInvocation invoke] + 362
16 XCTest 0x20103c6c -[XCTestCase invokeTest] + 221
17 XCTest 0x20103d7b -[XCTestCase performTest:] + 111
18 otest-shim-ios.dylib 0x0098fcc7 XCPerformTestWithSuppressedExpectedAssertionFailures + 172
19 otest-shim-ios.dylib 0x0098fc15 XCTestCase_performTest + 31
20 XCTest 0x20104c48 -[XCTest run] + 82
21 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139
22 XCTest 0x20104c48 -[XCTest run] + 82
23 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139
24 XCTest 0x20104c48 -[XCTest run] + 82
25 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139
26 XCTest 0x20104c48 -[XCTest run] + 82
27 XCTest 0x201066ba +[XCTestProbe runTests:] + 183
28 Foundation 0x03a4b5ec __NSFireDelayedPerform + 372
29 CoreFoundation 0x04054ac6 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
30 CoreFoundation 0x040544ad __CFRunLoopDoTimer + 1181
31 CoreFoundation 0x0403c538 __CFRunLoopRun + 1816
32 CoreFoundation 0x0403b9d3 CFRunLoopRunSpecific + 467
33 CoreFoundation 0x0403b7eb CFRunLoopRunInMode + 123
34 GraphicsServices 0x057495ee GSEventRunModal + 192
35 GraphicsServices 0x0574942b GSEventRun + 104
36 UIKit 0x01e7ff9b UIApplicationMain + 1225
37 Remind101 0x0008d184 main (main.m:16)
38 libdyld.dylib 0x046c5701 start + 1
NSManagedObjectContext Queue thread crashes:
Thread : Crashed: NSManagedObjectContext Queue
0 libobjc.A.dylib 0x03e250be objc_msgSend + 26
1 CoreData 0x0108ffe3 developerSubmittedBlockToNSManagedObjectContextPerform_privateasync + 83
2 libdispatch.dylib 0x044904d0 _dispatch_client_callout + 14
3 libdispatch.dylib 0x0447e047 _dispatch_queue_drain + 452
4 libdispatch.dylib 0x0447de42 _dispatch_queue_invoke + 128
5 libdispatch.dylib 0x0447ede2 _dispatch_root_queue_drain + 78
6 libdispatch.dylib 0x0447f127 _dispatch_worker_thread2 + 39
7 libsystem_pthread.dylib 0x047bfdab _pthread_wqthread + 336
8 libsystem_pthread.dylib 0x047c3cce start_wqthread + 30
There's small variations in the stack of the crashed thread, but it always includes developerSubmittedBlockToNSManagedObjectContextPerform_privateasync in the last couple of frames before a bad objc_msgSend.
My initial hypothesis was that something in my codebase was accessing MyObjectManager.managedObjectContext from off the main thread, which as I understand would be a bad time. But I put in a condition to log and pause if the accessor was called from a thread that was not the main thread, which was never hit, so there goes my low-hanging fruit on that one.
I also tried putting some logging into the entry and exit points of instances of the asynchronous NSManagedObjectContext::performBlock function in the RestKit library to see if a block was running longer than expected, holding onto a reference to the context, and dereferencing it after it had been destroyed. I would have expected a entry log without an exit log if this was the issue, but I didn't see that. I didn't try the same with performBlockAndWait because I'm assuming all synchronous operations are complete by the time my test case finished and resets the persistent store.
I'm really at a loss for even how to go about continuing my investigation into this. I realize it's not a ton to go on, but if anyone has ideas or proposals for tracking this down, I'd be happy to provide more information and try literally anything to get this resolved.
Here's what developerSubmittedBlockToNSManagedObjectContextPerform_privateasync actually does:
Gets a reference to the managed object context from within the queue
Creates it's own autorelease pool
Executes the block
Calls _processRecentChanges: on the managed object context to processing any pending user events
Drains the autorelease pool
Releases the block (the block was copied before it was passed to this method)
If the block was NULL at this point that would be a problem, but you would have different symptoms. The only things here that would use objc_msgSend are the autorelease pool and the message to _processRecentChanges:.
You can try setting a symbolic breakpoint on -[NSManagedObjectContext _processRecentChanges:] and see if that gives you any clues. It's very likely that RestKit is making some invalid assumptions about the lifetime of a managed object context and it's getting over released in your case. If that is true, it's also likely that the opposite error is being made elsewhere - that contexts are being overretained. The two problems more often than not go hand in hand. Your question doesn't include the reported reason for the crash (exception, EXC_BAD_ACCESS, etc.), so it's difficult to be definitive.
_processRecentChanges: gets called a lot, so it may still take some time to track this down. The issue would be easier to troubleshoot with the newer developer tools - you should be able to see what submitted the crashing block and from what queue, and you should be able to use Instruments with your test case. It's likely that if you can reproduce this with the newer tools that you will make progress troubleshooting it much faster.
I’m getting crash, and I can’t figure out what is causing it. Here what I’m getting from crash report:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000c
Triggered by Thread: 0
Thread 0 Crashed:
0 AVFoundation 0x2f271946 -[AVPlayerPeriodicCaller _effectiveRateChanged] + 418
1 AVFoundation 0x2f270fc8 __43-[AVPlayerTimelyCaller _timebaseDidChange:]_block_invoke + 232
2 libdispatch.dylib 0x3b04ed50 _dispatch_call_block_and_release + 8
3 libdispatch.dylib 0x3b04ed3c _dispatch_client_callout + 20
4 libdispatch.dylib 0x3b0516be _dispatch_main_queue_callback_4CF + 274
5 CoreFoundation 0x3039b674 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 4
6 CoreFoundation 0x30399f40 __CFRunLoopRun + 1304
7 CoreFoundation 0x303047a4 CFRunLoopRunSpecific + 520
8 CoreFoundation 0x30304586 CFRunLoopRunInMode + 102
9 GraphicsServices 0x352716ce GSEventRunModal + 134
10 UIKit 0x32c6388c UIApplicationMain + 1132
11 my-app 0x00029dd4 main (main.m:16)
12 libdyld.dylib 0x3b063ab4 start + 0
As I understand it’s coming from addPeriodicTimeObserverForInterval:queue:usingBlock:, so I’m always checking for block and queue to be correct. What else can cause this?
Thanks in advance.
UPDATE:
Here is method that calls addPeriodicTimeObserverForInterval:queue:usingBlock:
- (void)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block
{
[block copy];
dispatch_async(self.operationQueue, ^{
//This method just makes sure, that self.player not nil
[self someMethodcompletionHandler:^{
if (self.observer) {
[self.player removeTimeObserver:self.observer];
self.observer = nil;
}
if (block && queue) {
self.observer = [self.player addPeriodicTimeObserverForInterval:interval
queue:queue
usingBlock:block];
}
}];
});
}
UPDATE 2:
I figured it out. But I don’t know, why that works. So my question, why it works? Why self.operationQueue better than just queue?
self.observer = [self.player addPeriodicTimeObserverForInterval:interval
queue:self.operationQueue
usingBlock:^(CMTime time){
dispatch_async(queue, ^{
block(time);
});
}];
Official AVPlayer documentation states:
Releasing the observer object without invoking removeTimeObserver: will result in undefined behavior
This means that you should keep the value returned from addPeriodicTimeObserverForInterval:queue:usingBlock: and before the observer block is released make sure that you call removeTimeObserver:
Also note that block objects are allocated on the stack by default (not the heap) so to be sure that your block is not released when the frame ends you should retain the block by calling copy.
To read more about block memory management see here.
With my App I have a pre-populated sqlite DB that I created using core data from another app I created so the Data model is the same. I copy it over and everything works great. I tried it on every iOS device that can run iOS 6.0 because that is what I am building for. Even on the early iPod Touches the App works. It takes around 45 secs for the DB to copy over on the older devices. The app works all the data is there and all devices the tests were great and no issues. I released the app on the app store and found out that on the older devices the app is crashing when it first loads. I am assuming that it is a memory related issue. I am mostly confused that the customers that purchased it that I am in communication with have the same phone an iPhone 4S and one reports it works fine while the other says it crashes. I am thinking that one has a early 4S while the other has a later 4S. I confirmed that they had room on the phone to copy the data also. When I run the app from Xcode it never crashes no matter the device.
My Question is does any one know why this is happening and a possible fix?
Maybe there is a more efficient way that doesn't make the app take almost a min to load for the first time? Any help would be great because I am at a loss. I looked at about 30 other questions that are some what like this one but they really don't answer the question I need.
I would also just like to say Thank You to all of You because I live on this site and have learned a lot from all your questions and Answers.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Data.sqlite"];
#define UPGRADE_COPY_STORE_FROM_BUNDLE
#ifdef UPGRADE_COPY_STORE_FROM_BUNDLE
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
NSString *dataPath = [[NSBundle mainBundle]pathForResource:#"Data" ofType:#"sqlite" inDirectory:nil];
NSError *anyError = nil;
BOOL success = [[NSFileManager defaultManager] copyItemAtPath:dataPath toPath:[storeURL path] error:&anyError];
if (!success) NSLog(#"Error copying file: %#", anyError);
}
#endif
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
return _persistentStoreCoordinator;
}
Also attached is the Crash Log from a Device. Updated
Incident Identifier: CCFB748D-5A2A-45CE-B9EC-19811CCDC696
CrashReporter Key: 71b2c2b3b88abfe03baa87e7f588642dcec0ff08
Hardware Model: iPod4,1
Process: Upgrade [2513]
Path: /var/mobile/Applications/27C440D4-0210-48BB-A287-570FAEDE3369/Upgrade.app/Upgrade
Identifier: Upgrade
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2013-07-27 23:23:57.479 -0600
OS Version: iOS 6.1.2 (10B146)
Report Version: 104
Exception Type: 00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread: 0
Application Specific Information:
com.JonPhillips.Upgrade failed to launch in time
Elapsed total CPU time (seconds): 2.450 (user 2.450, system 0.000), 12% CPU
Elapsed application CPU time (seconds): 0.528, 3% CPU
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x39b84570 read + 8
1 libcopyfile.dylib 0x39a70df4 copyfile_internal + 4616
2 libcopyfile.dylib 0x39a72196 copyfile + 3326
3 Foundation 0x32301cb4 -[NSFilesystemItemCopyOperation _handleFTSEntry:] + 384
4 Foundation 0x323014a2 -[NSDirectoryTraversalOperation main] + 334
5 Foundation 0x322af5bc -[__NSOperationInternal start] + 836
6 Foundation 0x322fdd1e -[NSFileManager copyItemAtPath:toPath:error:] + 238
7 Upgrade 0x0009f438 -[JPPAppDelegate persistentStoreCoordinator] (JPPAppDelegate.m:186)
8 Upgrade 0x0009ef30 -[JPPAppDelegate managedObjectContext] (JPPAppDelegate.m:150)
9 Upgrade 0x0009f95e -[MainScreenViewController viewDidLoad] (MainScreenViewController.m:35)
10 UIKit 0x33849590 -[UIViewController loadViewIfRequired] + 360
11 UIKit 0x338c3fb8 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] + 80
12 UIKit 0x338c3f5e -[UITabBarController transitionFromViewController:toViewController:] + 26
13 UIKit 0x3386e05c -[UITabBarController _setSelectedViewController:] + 292
14 UIKit 0x3386e642 -[UITabBarController _selectDefaultViewControllerIfNecessaryWithAppearanceTransitions:] + 150
15 UIKit 0x338c6ca2 -[UITabBarController viewWillAppear:] + 130
16 UIKit 0x3389130c -[UIViewController _setViewAppearState:isAnimating:] + 132
17 UIKit 0x33849e10 -[UIView(Hierarchy) _willMoveToWindow:withAncestorView:] + 504
18 UIKit 0x3382c40e -[UIView(Internal) _addSubview:positioned:relativeTo:] + 326
19 UIKit 0x3382c2be -[UIView(Hierarchy) addSubview:] + 26
20 UIKit 0x33889e46 -[UIWindow addRootViewControllerViewIfPossible] + 270
21 UIKit 0x33885ae8 -[UIWindow _setHidden:forced:] + 360
22 UIKit 0x338c71e4 -[UIWindow makeKeyAndVisible] + 56
23 Upgrade 0x0009e896 -[JPPAppDelegate initializeStoryBoardBasedOnScreenSize] (JPPAppDelegate.m:64)
24 Upgrade 0x0009e106 -[JPPAppDelegate application:didFinishLaunchingWithOptions:] (JPPAppDelegate.m:22)
25 UIKit 0x3388aad4 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 248
26 UIKit 0x3388a65e -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1186
27 UIKit 0x33882846 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 694
28 UIKit 0x3382ac34 -[UIApplication handleEvent:withNewEvent:] + 1000
29 UIKit 0x3382a6c8 -[UIApplication sendEvent:] + 68
30 UIKit 0x3382a116 _UIApplicationHandleEvent + 6150
31 GraphicsServices 0x3551a5a0 _PurpleEventCallback + 588
32 GraphicsServices 0x3551a1ce PurpleEventCallback + 30
33 CoreFoundation 0x319f7170 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
34 CoreFoundation 0x319f7112 __CFRunLoopDoSource1 + 134
35 CoreFoundation 0x319f5f94 __CFRunLoopRun + 1380
36 CoreFoundation 0x31968eb8 CFRunLoopRunSpecific + 352
37 CoreFoundation 0x31968d44 CFRunLoopRunInMode + 100
38 UIKit 0x33881480 -[UIApplication _run] + 664
39 UIKit 0x3387e2fc UIApplicationMain + 1116
40 Upgrade 0x0009e0b8 main (main.m:16)
41 libdyld.dylib 0x39accb1c start + 0
Thread 1 name: Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0 libsystem_kernel.dylib 0x39b83648 kevent64 + 24
1 libdispatch.dylib 0x39abc4ec _dispatch_mgr_invoke + 792
2 libdispatch.dylib 0x39aaedf4 _dispatch_mgr_thread$VARIANT$up + 32
Thread 2 name: WebThread
Thread 2:
0 libsystem_kernel.dylib 0x39b82eb4 mach_msg_trap + 20
1 libsystem_kernel.dylib 0x39b83048 mach_msg + 36
2 CoreFoundation 0x319f7040 __CFRunLoopServiceMachPort + 124
3 CoreFoundation 0x319f5d9e __CFRunLoopRun + 878
4 CoreFoundation 0x31968eb8 CFRunLoopRunSpecific + 352
5 CoreFoundation 0x31968d44 CFRunLoopRunInMode + 100
6 WebCore 0x3794c500 RunWebThread(void*) + 440
7 libsystem_c.dylib 0x39aec30e _pthread_start + 306
8 libsystem_c.dylib 0x39aec1d4 thread_start + 4
Unknown thread crashed with unknown flavor: 5, state_count: 1
You are copying the data on the main thread, which blocks it far too long. It should never ever be blocked for 1 second or longer. Otherwise the iOS watchdog will kill your process.
The specific crash report shows the app was killed, because it took too long to start up: com.JonPhillips.Upgrade failed to launch in time.
The copy action is even running from inside applicationDidFinishLaunching. The watchdog timer is even shorter for having this method end! Check the WWDC sessions for exact timing if you are interested in them. I don't recall in which specifically it was mentioned.
If you require such tasks, move them to a background thread. If this tasks means that the user cannot do anything in the app, show a specific UI telling the user what is going on and giving some indication how long it will take, e.g. a progress bar, and/or some text "Step 1 of 3: Copying data".
I'm using GCD's dispatch_after method when my application is being loaded to perform some behavior. The intended behavior is to wait 3 seconds from the end of applicationDidFinishLaunchingWithOptions to perform a selector that runs in a background queue.
I haven't experienced any crashes on my test devices, but I have user crash reports of uncaught SIGBUS signals, the cause being a BUS_ADRALN exception. From my understanding of this code, a BUS_ADRALN error indicates an address alignment error.
This is how I'm creating my timer:
double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
^(void){
[self methodToPerformInBackground];
});
What could be causing this crash?
Since multithreading errors can be a strange sort of beast, I'm going to throw out some ideas that I've been tossing around in my head.
I'm calling this from within a call to [self performSelectorOnMainThread:withObject:waitUntilDone]. Is there something problematic about doing this within a selector called this way?
Since I'm calling dispatch_get_global_queue and not dispatch_create_queue, I don't need to retain the queue returned by this method. Is this reasoning correct?
In this code, self is the application delegate. Could the crash be caused trying to perform the block after the application enters the background or terminates? Would the application automatically clean up any dispatched blocks upon closing?
Something inside the method being called is causing the crash, but GCD doesn't provide a stack trace to it.
Edit: I'd rather not include the code that's called in the block, since I'm not convinced that's the main problem anyway. Here is the stack trace. The crash on thread 0 makes it seem as though the issue was in GCD, not the code called in the block.
Edit #2: I have strange news to share after going through more crash reports. This crash is only appearing for users running iOS 4.2.X and below. Since GCD is supported for iOS 4.0 and later, my guess is there was a bug patched in 4.3.
Thread 0 Crashed:
0 libSystem.B.dylib 0x35e5fb10 _dispatch_retain + 0
1 libSystem.B.dylib 0x35e5df8c dispatch_after_f + 80
2 libSystem.B.dylib 0x35e5e070 dispatch_after + 72
3 MyApplication 0x0000466c -[MyApplicationDelegate applicationDidFinishLaunchingPart2:] (MyApplicationDelegate.m:366)
4 CoreFoundation 0x37538f79 -[NSObject(NSObject) performSelector:withObject:] + 25
5 Foundation 0x35171e6d __NSThreadPerformPerform + 273
6 CoreFoundation 0x375518d1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
7 CoreFoundation 0x37521ecd __CFRunLoopDoSources0 + 385
8 CoreFoundation 0x375216f9 __CFRunLoopRun + 265
9 CoreFoundation 0x3752150b CFRunLoopRunSpecific + 227
10 CoreFoundation 0x37521419 CFRunLoopRunInMode + 61
11 GraphicsServices 0x33e76d24 GSEventRunModal + 196
12 UIKit 0x3591d57c -[UIApplication _run] + 588
13 UIKit 0x3591a558 UIApplicationMain + 972
14 MyApplication 0x00003024 main (main.m:113)
Thread 1:
0 libSystem.B.dylib 0x35d8f974 kevent + 24
1 libSystem.B.dylib 0x35e5dd70 _dispatch_queue_invoke + 104
2 libSystem.B.dylib 0x35e5d790 _dispatch_worker_thread2 + 128
3 libSystem.B.dylib 0x35de6978 _pthread_wqthread + 400
Thread 2:
0 libSystem.B.dylib 0x35de72fc __workq_kernreturn + 8
Thread 3:
0 libSystem.B.dylib 0x35d5b3b0 mach_msg_trap + 20
1 CoreFoundation 0x37521f83 __CFRunLoopServiceMachPort + 95
2 CoreFoundation 0x37521787 __CFRunLoopRun + 407
3 CoreFoundation 0x3752150b CFRunLoopRunSpecific + 227
4 CoreFoundation 0x37521419 CFRunLoopRunInMode + 61
5 WebCore 0x3318bd1c _ZL12RunWebThreadPv + 532
6 libSystem.B.dylib 0x35de5b4c _pthread_start + 372
Thread 4:
0 libSystem.B.dylib 0x35d5b3b0 mach_msg_trap + 20
1 CoreFoundation 0x37521f83 __CFRunLoopServiceMachPort + 95
2 CoreFoundation 0x37521787 __CFRunLoopRun + 407
3 CoreFoundation 0x3752150b CFRunLoopRunSpecific + 227
4 CoreFoundation 0x37521419 CFRunLoopRunInMode + 61
5 Foundation 0x3517ec55 +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:] + 217
6 Foundation 0x3515cb91 -[NSThread main] + 49
7 Foundation 0x35155b97 __NSThread__main__ + 915
8 libSystem.B.dylib 0x35de5b4c _pthread_start + 372
DISPATCH_QUEUE_PRIORITY_BACKGROUND is an iOS 5.0+ feature. If you try to use it on iOS 4.x it will be NULL (which will crash when you try to retain it, since GCD is a C-library and it is not safe to use NULL the way it is to use nil in objective-c). See this answer for more info. The solution is to use low priority instead, or use preprocessor directives to switch between the two.