On Demand Resources - unexpected crash on iOS 11

Originator:dlahyani
Number:rdar://34998340 Date Originated:15/10/2016
Status:Closed Resolved:Duplicate of 31574191
Product:iOS 11 Product Version:11.x
Classification:Crash Reproducible:Not Reproduceable
 
Area:
Foundation

Summary:
We've seen a repeating crash on client devices running iOS 11 (only iOS 11). The crash seem to be related to On-Demand Resources mechanism as the exception message says: "Fatal Exception: NSInvalidArgumentException
Unexpected state upon completion of beginAccessingResourcesWithCompletionHandler (3)"

We were unable to re-produce this crash in lab conditions. We can see that it happens to a relatively small portion of our users but for these users it occurs repeatedly.

This is the stack trace of the crashing thread (non-main thread):
Fatal Exception: NSInvalidArgumentException
0  CoreFoundation                 0x183bb3d38 __exceptionPreprocess
1  libobjc.A.dylib                0x1830c8528 objc_exception_throw
2  Foundation                     0x1845ff670 __copy_helper_block_.385
3  Foundation                     0x1846c5f2c __NSXPCCONNECTION_IS_CALLING_OUT_TO_ERROR_BLOCK__
4  Foundation                     0x1846c5eac -[NSXPCConnection _decodeAndInvokeReplyBlockWithEvent:sequence:replyInfo:]
5  Foundation                     0x1846ca0d4 __88-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:]_block_invoke.346
6  libxpc.dylib                   0x183819a0c _xpc_connection_reply_callout
7  libxpc.dylib                   0x183819948 _xpc_connection_call_reply_async
8  libdispatch.dylib              0x183539758 _dispatch_client_callout3
9  libdispatch.dylib              0x183551060 _dispatch_mach_msg_async_reply_invoke$VARIANT$mp
10 libdispatch.dylib              0x183542d00 _dispatch_queue_serial_drain$VARIANT$mp
11 libdispatch.dylib              0x1835437d8 _dispatch_queue_invoke$VARIANT$mp
12 libdispatch.dylib              0x183544200 _dispatch_root_queue_drain_deferred_wlh$VARIANT$mp
13 libdispatch.dylib              0x18354c4a0 _dispatch_workloop_worker_thread$VARIANT$mp
14 libsystem_pthread.dylib        0x1837defe0 _pthread_wqthread
15 libsystem_pthread.dylib        0x1837dec30 start_wqthread

Steps to Reproduce:
Unknown.

Expected Results:
beginAccessingResourcesWithCompletionHandler invokes the completion handler with relevant error instead of crashing.

Actual Results:
The NSXPC connection crashes when it tries to send the reply to the ODR request.

Version/Build:

The crash occurs on many different versions of our apps, but all crashes are on iOS 11 (including 11.0.0, 11.0.1, 11.0.2, 11.0.3 and 11.1.0).

Comments

I have been experiencing this issue as well, but have not seen any reports of it from users running iOS 12. Perhaps it's been resolved? I'd love to hear if anyone else has seen this from an iOS 12 user.

I have the exact issue in my app, the code is as per apple's requirement

  • (void)odr_beginAccessingResourcesForDeviceType:(AXMilitaryObjectType)deviceType completionHandler:(void (^ _Nonnull)(NSError * _Nullable error))completionHandler {

    if ( !self.canUseODR ) return;

    NSString *tag = [self odr_tagForDevice:deviceType];

    NSBundleResourceRequest *request = [[NSBundleResourceRequest alloc] initWithTags:[NSSet setWithObject:tag]];

    LOG_UI(LEVEL_INFO, @"ODR resoruces requested for tag '%@'", tag);

    __weak typeof(self) weakSelf = self;

    [request conditionallyBeginAccessingResourcesWithCompletionHandler:^(BOOL resourcesAvailable) {

    dispatch_async(dispatch_get_main_queue(), ^{
    
        // resources available - no need to do anything
    
        if ( resourcesAvailable ) {
    
            LOG_UI(LEVEL_INFO, @"ODR resources are cached for tag '%@'", tag);
    
            weakSelf.canUseODR = NO;
    
            completionHandler(nil);
        }
    
        // resources should be downloaded first
    
        else
    
            [weakSelf.odrRequest beginAccessingResourcesWithCompletionHandler:^(NSError * _Nullable error) {
    
                dispatch_async(dispatch_get_main_queue(), ^{
    
                    if ( error ) {
    
                        LOG_UI(LEVEL_WARNING, @"ODR resoruces failed to download for tag '%@' with error %@", tag, error.localizedDescription);
    
                        weakSelf.odrRequest = nil;
    
                    } else
    
                        LOG_UI(LEVEL_INFO, @"ODR resources downloaded for tag '%@'", tag);
    
                    weakSelf.canUseODR = NO;
    
                    completionHandler(error);
                });
    
            }];
    
    });
    

    }];

    self.odrRequest = request;

}

By WoodenSoldierSaurman at Oct. 30, 2017, 8:59 a.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!