User Interaction sometimes triggers a crash in UIGestureGraphEdge

Originator:tapi
Number:rdar://28209432 Date Originated:September 8 2016
Status:Open Resolved:
Product:iOS SDK Product Version:iOS 10
Classification:Serious Reproducible:Sometimes
 
-- Update:
So after some more investigation we were able to find out the cause and create an isolated reproduction case.
We were instantiating our applications root view controller in the init method of our application delegate. This is something that worked for us in iOS 8 and 9 and only started causing problems on iOS 10.
Unfortunately i've deleted all my Xcode 8 betas and cannot provide any suggestions as to when this change was introduced.

'UIGestureGraphEdge-Crash.zip' was successfully uploaded.

Summary:
Almost any interaction in our app will trigger an assertion failure in UIGestureGraphEdge.
Crash occurs both in simulator and on device.

Forum post about issue: https://forums.developer.apple.com/thread/61432

*** Assertion failure in -[UIGestureGraphEdge initWithLabel:sourceNode:targetNode:directed:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.6/Source/GestureGraph/UIGestureGraphEdge.m:25

Steps to Reproduce:
Unfortunately I have not been able to reproduce this issue in a sample application but can reliably reproduce it in our app with almost any interaction including
- UIBarBarButtonItems
- Scrollview Interactions (swipes, pans, etc)
- Maybe taps that are un-handled and propagating up to the window (suspicion, based on debug values.)

UITabBar interactions appear to be unaffected at least in my particular case


Expected Results:
Private classes that call other private classes methods do so with the correct parameters

Actual Results:
It appears as though a nil value is occurring in the stack trace in [UIGestureEnvironment _addDynamicRequirementForGestureRecognizer:requiringGestureRecognizerToFail:] which later propagates down to [UIGestureGraphEdge initWithLabel:sourceNode:targetNode:directed:] where the crash occurs.

I put the UIKit simulator SDK through Hopper and looked at the methods preceding the method that crashed to help me step through the assembly while debugging.

The bug looks like it comes from the following method
void -[UIGestureEnvironment _addDynamicRequirementForGestureRecognizer:requiringGestureRecognizerToFail:](void * self, void * _cmd, void * arg2, void * arg3) {
    r15 = [arg2 retain];
    r14 = [[self _nodeForGestureRecognizer:arg3] retain];
    r12 = [self _nodeForGestureRecognizer:r15];
    [r15 release];
    r15 = [r12 retain];
    rax = [self->_dependencyGraph addUniqueEdgeWithLabel:@"dynamicFailureRequirement" sourceNode:r14 targetNode:r15 directed:0x1 properties:stack[2048]];
    objc_unsafeClaimAutoreleasedReturnValue(rax);
    [r15 release];
    rdi = r14;
    [rdi release];
    return;
}

Note that the second call to _nodeForGestureRecognizer is not followed immediately by a retain the way the first call is. Putting a symbolic breakpoint at [UIGestureEnvironment _addDynamicRequirementForGestureRecognizer:requiringGestureRecognizerToFail:]+84 in both my app and a sample app with a similar UI setup. In the sample app the register r12 has a value that survives long enough to make it further down the call stack to the UIGestureGraphEdge method. In my app however register r12 is nil which eventually leads to the crash.

Version:
Simulator iOS10(14A345), Device iOS10(14A403)

Notes:
Attached:
- log of printed values from debug session
- screen shot of debugging session
- stack trace

Configuration:
iPhone 6 Plus Simulator, iPhone 6

Attachments:
'Screen Shot 2016-09-08 at 12.28.00 PM.png', 'Stack trace' and 'debug values from log' were successfully uploaded.

Comments


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!