Repository navigation
Linux shell/embedder do not shutdown Dart root isolate when exiting #132404
Description
Is there an existing issue for this?
- I have searched the existing issues
- I have read the guide to filing a bug
Steps to reproduce
- Create base project with
flutter create --platform=linux - Run the app
- Close the application by closing button of the window
(This works also when calling SystemNavigator.pop()
Expected results
Window is properly detached from flutter view and root isolate is properly shut down.
Actual results
GTK runloop (g_application_run in main.cc of standard linux embedder of application) returns directly and the process exits immediately without the window to be properly detached.
Sometimes, this causes an abort before process exit and this is considered as an abnormal exit of the program.
Code sample
This is reproducible using template project created with flutter create.
Screenshots or Video
No response
Logs
No response
Flutter Doctor output
[✓] Flutter (Channel stable, 3.10.6, on Arch Linux 6.4.8-arch1-1, locale en_US.UTF-8)
• Flutter version 3.10.6 on channel stable at /opt/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision f468f33 (4 weeks ago), 2023-07-12 15:19:05 -0700
• Engine revision cdbeda788a
• Dart version 3.0.6
• DevTools version 2.23.1
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
• Android SDK at /opt/android-sdk/
• Platform android-33, build-tools 33.0.2
• ANDROID_HOME = /opt/android-sdk
• Java binary at: /opt/android-studio/jbr/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
• All Android licenses accepted.
[✓] Chrome - develop for the web
• CHROME_EXECUTABLE = chromium
[✓] Linux toolchain - develop for Linux desktop
• clang version 15.0.7
• cmake version 3.27.1
• ninja version 1.11.1
• pkg-config version 1.8.1
[✓] Android Studio (version 2022.2)
• Android Studio at /opt/android-studio
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
[✓] Connected device (3 available)
• Pixel 7 (mobile) • 29261FDH2000H5 • android-arm64 • Android 13 (API 33)
• Linux (desktop) • linux • linux-x64 • Arch Linux 6.4.8-arch1-1
• Chrome (web) • chrome • web-javascript • Chromium 115.0.5790.170 Arch Linux
[✓] Network resources
• All expected network resources are available.
• No issues found!
Activity
huycozy commentedon Aug 14, 2023
Could you be more specific on the Actual result? Is there an example that demonstrates
abnormal exitmore intuitively?ndusart commentedon Aug 21, 2023
The Dart VM is not properly shutdown during app normal exit. (this is not an
abnormal exitcondition here)You can verify it in the engine code by monitoring that
root_isolate_shutdown_callbackis not executed.I managed to detect that on my custom branch
The issue here is that Dart VM do not properly clean its resources and one consequence of this is that
NativeFinalizerare not collected and do not call its callback, while it is a strong guarantee of this.The following example can be run in order to see that NativeFinalizer callback is not called when exiting application using window close button or calling
SystemNavigator.pop().Example project
main.dart:
mraleph commentedon Aug 22, 2023
(Removing
dependency: dartbecause it is purely engine / embedding fix)ndusart commentedon Aug 22, 2023
hello @mraleph, thanks for the heads up.
Could you confirm this sounds to be due to how flutter is interacting with the Dart VM more than an issue in dart ?
I am discussing on a Discord thread and they imply I should probably move that ticket to dart directly.
I am not conviced this is related to dart but indeed is a defect in how flutter manage the dart vm. Would you like to share your opinion on this ?
Thanks :)
gspencergoog commentedon Aug 24, 2023
As we discussed on the Discord thread, our philosophy on this issue is that providing a notification that isn't reliable gives a false sense of security to app developers that we don't want to leave them with. (Desktop Triage)
In your case, are you asking for a plugin API that notifies about the application exit, or a Framework notification through the
AppLifecycleListeneror bindings?For posterity (in case the Discord record disappears), here's part of the OP's problem statement:
ndusart commentedon Aug 31, 2023
This issue is more generic about how the close of the application can abruptly shutdown the dart VM without any notice.
This can be visualised more specifically by seeing how
SystemNavigator.pop()very often crashes the process on Linux. There is clearly a race condition where given the timing, this may just exit the process without causing any problem but it is very easy to create an abort condition in a simple basic project only callingSystemNavigator.pop()in a push of a button.This let met think that the engine or the embedder may need to properly handle the process exit to cleanly stop threads and release some resources. If you think you should fix
SystemNavigator.pop()to do something else than basically callingexit(0)(which it does now) to let the flutter engine code to close properly, I'd be interested to know the reasons why letting handle some (not all, just the same as the ones handled by the engine) exit condition is not applicable to app code as well.The initial point of this specific issue was that imho at very least, Dart VM should be properly shutdown. This would let plugin developers rely on
NativeFinalizerto be executed on normal exit conditions.You seem to disagree but actually exit condition that are not catchable already have the expected behavior for app developers, we do not need more guarantees, because in all platforms, an uncatchable exit condition express itself as a crash condition or clear stop of any code execution (e.g. power loss) and in the case the system is still running, OS will recover most if not all resources. This is expected and developers can code around these facts.
The problematic case in Flutter environment are normal exit condition, which are effectively catchable and reliable.
In these conditions, either:
Exit notification is somewhat helping. Since 3.13, Linux is better served because we can at least now intercept the click on the close button of the main window by listening for
didRequestAppExitcallback.But, consider app developers depending on some native plugins (they probably even don't know the fact that they are native). They now have to know that they should explicitely close an object/controller/handle from a native plugin to release some unknown resources because this plugin cannot rely on
NativeFinalizerto fire under normal exit conditions in all platforms. This close operation should be also called in multiple callback notifying for exit condition because every platform has a different mechanism.That's highly unexpected and that's causing confusion and issues here and there.
From my experience, mobile platforms are properly closing the dart VM and we can rely on
NativeFinalizeron these. Cannot speak about other desktop platforms, but adding this behavior on Linux would help unify how we can manage native resources. And moreover, this could even be transparent to plugin users.flutter-triage-bot commentedon Jun 6, 2024
The
triaged-desktoplabel is irrelevant if there is noteam-desktoplabel orfyi-desktoplabel.