Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XCTests using Texture/AsyncDisplayKit deadlock during initialisation when targeting iOS 15 #2029

Open
benniebotha opened this issue Sep 22, 2021 · 22 comments

Comments

@benniebotha
Copy link

While running the test, AsyncDisplayKit hangs before any tests run when iOS 15 is used as the test target.
It appears to hang inside -[UIView init] which indicates there may be an issue with UIKit itself. This issue has been raised with Apple, but implementing a fix in Texture is needed in the meantime.

In AsyncDisplayKit we can see that the hang occurs in the following functions:

__attribute__((constructor)) static void ASLoadFrameworkInitializer(void)
{
  ASInitializeFrameworkMainThread();
}
void ASInitializeFrameworkMainThread(void)
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    ASDisplayNodeCAssertMainThread();
    // Ensure these values are cached on the main thread before needed in the background.
    if (ASActivateExperimentalFeature(ASExperimentalLayerDefaults)) {
      // Nop. We will gather default values on-demand in ASDefaultAllowsGroupOpacity and ASDefaultAllowsEdgeAntialiasing
    } else {
      CALayer *layer = [[[UIView alloc] init] layer];
      allowsGroupOpacityFromUIKitOrNil = @(layer.allowsGroupOpacity);
      allowsEdgeAntialiasingFromUIKitOrNil = @(layer.allowsEdgeAntialiasing);
    }
    ASNotifyInitialized();
#if AS_SIGNPOST_ENABLE
    _ASInitializeSignpostObservers();
#endif
  });

It appears the hang is during the call to [[UIView alloc] init] inside the dispatch_once.

@foxware00
Copy link
Contributor

foxware00 commented Sep 22, 2021

@benniebotha I can confirm i'm seeing the same thing. Would you be able to link to the Apple issue for tracking? Oddly I'm also seeing the same result very occasionaly running the app itself. It will freeze on a splash screen before didFinishLaunchingWithOptions is called and will prevent the app launching at all.

@nguyenhuy I don't suppose one of the team could look into this?

@foxware00
Copy link
Contributor

@benniebotha changing the ASInitializeFrameworkMainThread function to the following allows the tests to pass. I believe it's also the defaults fetched from the layer. I don't override this stuff in the .plist so it's an acceptable workaround for the meantime.

void ASInitializeFrameworkMainThread(void)
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    ASDisplayNodeCAssertMainThread();
    // Ensure these values are cached on the main thread before needed in the background.
    if (ASActivateExperimentalFeature(ASExperimentalLayerDefaults)) {
      // Nop. We will gather default values on-demand in ASDefaultAllowsGroupOpacity and ASDefaultAllowsEdgeAntialiasing
    } else {
      allowsGroupOpacityFromUIKitOrNil = @(YES); // Use default values here instead of loading the layer
      allowsEdgeAntialiasingFromUIKitOrNil = @(NO);
    }
    ASNotifyInitialized();
#if AS_SIGNPOST_ENABLE
    _ASInitializeSignpostObservers();
#endif
  });
}

@benniebotha
Copy link
Author

Thanks @foxware00 for looking into it further. The fact that it is occasionally happening outside of tests is even more concerning! I raised the issue under the dev tools feedback that is unfortunately not public. 😞 Your solution would does seem to work yes. Another work around seems to be activating the ASExperimentalLayerDefaults experiment. I haven't worked on Texture a lot, could you point me to the documentation on how these experiments work?

@foxware00
Copy link
Contributor

Thanks @foxware00 for looking into it further. The fact that it is occasionally happening outside of tests is even more concerning! I raised the issue under the dev tools feedback that is unfortunately not public. 😞 Your solution would does seem to work yes. Another work around seems to be activating the ASExperimentalLayerDefaults experiment. I haven't worked on Texture a lot, could you point me to the documentation on how these experiments work?

Yes it's very concerning, I can't say 100% that it's Texture during normal boot as i'm currently unable to get a spindump when it happens. However the result (freezing before the app boots without any logs) is identical to that shown when running UITests

In terms of the Experimental flags, I'm not 100% sure having not used them in the past. Which package manager are you using, you can point Cocoapods at a github fork with the changes mentioned above if it would satisfy you in the meantime?

@foxware00
Copy link
Contributor

@nguyenhuy I've had a response from eskimo at Apple and has indicated that the framework intialisation is at fault. He has suggested a couple of work arounds such as lazily initalizing the framework. Are you able to take a look at this and see if there is anything we can do?

https://developer.apple.com/forums//thread/689592?answerId=688696022&replyId=688696022

@MikePendo
Copy link

Any progress on this issue as we also experience it and we r heavy dependent on Texture.
(or possible work around would )

@MaximShnirman
Copy link

same issue here

@benniebotha
Copy link
Author

Thanks @foxware00 for raising it on the Apple forum. I got the experiment working as well as making those temporary changes in our fork. That should do for now thanks.

Hopefully it will get solved quickly on the main repo.

@foxware00
Copy link
Contributor

@benniebotha the solution we've aludded too seems to fix unit tests but still happens in the main app for a subset of users.

It would be good to have some weigh in from some of the authors as my knowledge of Objective-C and framework initalisers is limited.

@garrettmoon @nguyenhuy @appleguy @Adlai-Holler

@foxware00
Copy link
Contributor

Thanks @foxware00 for raising it on the Apple forum. I got the experiment working as well as making those temporary changes in our fork. That should do for now thanks.

Hopefully it will get solved quickly on the main repo.

@benniebotha It might be worth also rasing a compatability bug with Apple, the more people shouting the more likely they are to fix it.

@GeekTree0101
Copy link
Contributor

#2032 I just open Pull-Request. It replace attribute from constructor to destructor for run after main on running unit test

@galgord
Copy link

galgord commented Sep 30, 2021

same issue here

@noambartouv
Copy link

experiencing similar issue

@jeffersonsetiawan
Copy link

Really curious why this only/always happen in unit test but not in application itself

@brandtdaniels
Copy link

Really curious why this only/always happen in unit test but not in application itself

Any why only starting with iOS 15 / Xcode 13

@dimanitm
Copy link

Same here

denkeni added a commit to Ptt-official-app/Ptt-iOS that referenced this issue Nov 27, 2021
Unit testing will be stuck on Xcode 13. See: TextureGroup/Texture#2029
@MikePendo
Copy link

MikePendo commented Nov 28, 2021

I still don't understand how that related to the tests?
Why the test got stuck even though the Texture related code wasn't invoke, (I see some dynamic invocation when loading the library I am not sure why its needed as fo example in our test cases we don't even use Texture so its kinda redundant and now causing some strange issues).
Apparently I see some strange issue with cornerradius with and without that patch
Ok I have looked a little bit in the code and apparently u r initializing some UI components on load time for instance here:
ASInitializeFrameworkMainThread
That what cause some issues on our side in general according to Apple docs u should not init any heavy object during load time (not sure why it was done that way, removing the initialization to more proper place seems to resolve the issue).

@lucasromanomr
Copy link

Same here

@denkeni
Copy link

denkeni commented Dec 9, 2021

#2032 has been merged, so this issue has got fixed and could be closed. Check out the current master branch.

@musakokcen
Copy link

musakokcen commented Dec 20, 2021

Hey! It looks like this pr #2032 does not solve the issue. @foxware00 's this solution works.

@christiankm
Copy link

We're experiencing the same issue. Is there any way we can assist here, to resolve this?

@richieshilton
Copy link

Is there any update on this getting fixed in a release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests