Skip to content

Engine v1.12.13-hotfixes has bug when using AddToApp #52455

@xujim

Description

@xujim

hi, I found engine v1.12.13-hotfixes is not ok with the add to app. When I pushed multiple FlutterViewController and pop back, the app will crash due to accessing the nulled surface in Rasterizer::Setup. Here is my mini example to reproduce the problem: https://github.com/xujim/testaccessibility

The steps to reproduce the crash

Here is my add to app example to reproduce the crash bug:
https://github.com/xujim/testaccessibility
With this example installed, you just need to "Open Flutter Page", and again and again, then pop back the VC, finally, it crashed.

The Root Cause Analysis

It is caused by the sequence of Setup and Teardown of Rasterizer in the addToApps circumstance.
In the addToApps, we need to push and pop multiple VC, it will lead to setup and teardown of surface more than one time. And the setup and teardown tasks are queued by GPU thread.
However, note that the surface is held by on Engine, and the underlying memory is shared by the tasks(setup and teardown task) in the GPU thread queue. This will cause a situation, that a setup task need to access surface which has just been teardown in the last teardown task. Just as following diagram:
image

Change the Rasterizer::Setup function this way can avoid the crash, even though it might be not the best fix:
image

My Flutter Version

 testaccessibility git:(master) ✗ flutter doctor -v
[✓] Flutter (Channel v1.12.13-hotfixes, v1.12.13+hotfix.8, on Mac OS X 10.14.6
    18G95, locale zh-Hans-CN)
    • Flutter version 1.12.13+hotfix.8 at
      /Users/yujie/Desktop/FlutterWork/flutter_Github
    • Framework revision 0b8abb4724 (4 周前), 2020-02-11 11:44:36 -0800
    • Engine revision e1e6ced81d
    • Dart version 2.7.0

Activity

xujim

xujim commented on Mar 12, 2020

@xujim
Author

@xster please take a look

added
a: existing-appsIntegration with existing apps via the add-to-app flow
engineflutter/engine repository. See also e: labels.
c: crashStack traces logged to the console
on Mar 12, 2020
kangwang1988

kangwang1988 commented on Mar 12, 2020

@kangwang1988
Contributor
added this to the March 2020 milestone on Mar 12, 2020
xster

xster commented on Mar 12, 2020

@xster
Member

@gaaclarke can you take a look?

dnfield

dnfield commented on Mar 12, 2020

@dnfield
Contributor

Does this bug still exist on master?

xujim

xujim commented on Mar 12, 2020

@xujim
Author

I am afraid it still exist

dnfield

dnfield commented on Mar 12, 2020

@dnfield
Contributor

Hm. Both the Android and the iOS embedding believe they can return nullptr in CreateRenderingSurface if they have no surface to work with, which can happen if they get that call without having a view to work with (or, before having a view to work with).

That should only be valid if there really is no View to work with. But in this case, there should be.

I haven't traced this all the way through, but it seems like we might not be calling NotifyCreated properly in this case - it also seems like we should not try to setup the rasterizer if there is in fact no surface to work with.

/cc @chinmaygarde @amirh @cyanglaz

@gaaclarke probably has more recent context on this than I do as well but those people might be interested in the platform view/rasterizer aspects.

changed the title [-]Engine v1.12.13-hotfixes have bug when using AddToApp[/-] [+]Engine v1.12.13-hotfixes has bug when using AddToApp[/+] on Mar 12, 2020

12 remaining items

xster

xster commented on Mar 18, 2020

@xster
Member

@xujim what you're describing sounds reasonable to me. Does it work if you manually set the engine.viewController to nil or to the top vc before the bottom vc gets covered? Seems like that's what https://github.com/xujim/testaccessibility/compare/master...foxsofter:fix_crash?expand=1#diff-a6425004106bb459a3f91283fe144fd2 is doing right?

This bug is essentially asking us to make initWithEngine more ergonomic by having the FlutterViewController remove the previous FlutterViewController from the engine automatically?

xster

xster commented on Mar 18, 2020

@xster
Member

Posterity: from chatting with @gaaclarke documentation and ergonomics around this may all end up bundled in the #37644 work as well.

xujim

xujim commented on Mar 21, 2020

@xujim
Author

@xster , thanks, fix_crash works for my example, but it needs to hook the UINavigationController, which is not so nice. I finally figured out a workaround, which is better for me——try not call surfaceUpdated:NO for my FlutterViewController. This way, we can make sure the flutter engine holding an ios_surface_ until it is reset by SetOwnerViewController as soon as another FlutterVC is attached to FlutterEngine.

xujim

xujim commented on Mar 21, 2020

@xujim
Author

The cons of my solution is that need to override the viewDidDisappear of FlutterViewController, which will lose the TRACE_EVENT0. So, I do believe @gaaclarke 's words that it is not supported flow by flutter:(
Hopefully, you guys can support this flow, I think it is reasonable.
My code as following:

//in this way, we can call FlutterViewController's parent in FLBFlutterViewContainer
@interface FlutterViewController (bridgeToviewDidDisappear)
- (void)flushOngoingTouches;
- (void)override_viewDidDisappear:(BOOL)animated;
@end

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
@implementation FlutterViewController (bridgeToviewDidDisappear)
- (void)bridge_viewDidDisappear:(BOOL)animated{
//    TRACE_EVENT0("flutter", "viewDidDisappear");
    [self flushOngoingTouches];
    [super viewDidDisappear:animated];
}
@end

//my VC inherited from FlutterViewController
@implementation FLBFlutterViewContainer 
- (void)viewDidDisappear:(BOOL)animated
{
    [BoostMessageChannel didDisappearPageContainer:^(NSNumber *result) {}
                                                pageName:_name
                                                  params:_params
                                                uniqueId:self.uniqueIDString];

    if (FLUTTER_VC.beingPresented || self.beingDismissed /*|| ![self.uniqueIDString isEqualToString:[(FLBFlutterViewContainer*)FLUTTER_VC uniqueIDString]]*/)
    {
        [FLUTTER_APP resume];
        [(FLBFlutterViewContainer*)FLUTTER_VC surfaceUpdated:YES];
    }

    //call super's super implementation
    [self bridge_viewDidDisappear:animated];
}
@end 
lock

lock commented on Apr 4, 2020

@lock

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

locked and limited conversation to collaborators on Apr 4, 2020
unlocked this conversation on Apr 10, 2020
lock

lock commented on Apr 25, 2020

@lock

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

locked and limited conversation to collaborators on Apr 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

a: existing-appsIntegration with existing apps via the add-to-app flowc: crashStack traces logged to the consolecustomer: alibabaengineflutter/engine repository. See also e: labels.platform-iosiOS applications specifically

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @xster@kangwang1988@foxsofter@xujim@dnfield

      Issue actions

        Engine v1.12.13-hotfixes has bug when using AddToApp · Issue #52455 · flutter/flutter