Repository navigation
Description
Steps to reproduce
flutter create --platforms=linux bug- In
linux/runner/my_application.cc, add the code below. It opens a secondGtkWindowwhoseFlViewis created withfl_view_new(), so it has its ownFlEngine, and destroys that window after 5 seconds. flutter run -d linux --release- Wait about 6 seconds. The sample forces a repaint of the first window 1 second after destroying the second one. Hovering over or clicking the first window triggers the same crash.
Expected results
The second window and its engine go away, and the first window keeps working.
Actual results
The app crashes with SIGSEGV at the next repaint of the remaining window. The crash happens on the GTK main thread, inside gdk_window_end_draw_frame(), right after GDK logs eglMakeCurrent failed five times. See the logs below.
Test environment: Ubuntu 26.04, GNOME on Wayland, Flutter 3.47.7 stable.
| Driver | Result |
|---|---|
| NVIDIA proprietary 595.84 (RTX 5060 Ti) | Crashed 3/3 |
Mesa llvmpipe (__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json LIBGL_ALWAYS_SOFTWARE=1) |
Crashed 4/4 |
Analysis
fl_opengl_manager_dispose()inshell/platform/linux/fl_opengl_manager.ccdestroys its three contexts and then callseglTerminate(self->display).- The display comes from
eglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, gdk_wayland_display_get_wl_display(...)). Per the EGL spec, this returns the sameEGLDisplayfor the same native display. So the display is shared by everyFlEnginein the process and by GDK's own GL contexts. - EGL displays are not reference counted, unless
EGL_KHR_display_referenceis used. Disposing any one engine therefore terminates EGL for everyone, and the next GDK repaint fails. - Every engine creates an
FlOpenGLManagerinfl_engine_init(). This affects any app or plugin that disposes one of several engines, for example multi-window plugins such as desktop_multi_window (one engine per window) and headless engines.
Evidence from gdb:
- A breakpoint on
eglTerminateshows it is called from the engine's dispose (g_object_unrefchain) right after the second window is destroyed. TheeglMakeCurrent failedwarnings and the crash follow. - Making
eglTerminatereturnEGL_TRUEwithout running it (gdbreturn 1at the breakpoint) removes the crash completely. The first window keeps working.
The code is unchanged on master (fl_opengl_manager.cc, checked on 2026-10-14).
Suggested fix: don't call eglTerminate() in fl_opengl_manager_dispose(), because the display belongs to the process and GDK, not to one engine. Alternatively, share one reference-counted manager per display and terminate only when the last one is disposed.
Related: MixinNetwork/flutter-plugins#488 (desktop_multi_window: closing a child window crashes the app on Linux).
Side note: fl_view_dispose() also calls fl_engine_remove_view() for the implicit view. This logs 'FlutterEngineRemoveView' returned 'kInvalidArguments' ... The implicit view cannot be removed. The message is harmless and also appears when nothing crashes, but the call could be skipped for the implicit view.
Code sample
Code sample (additions to linux/runner/my_application.cc of `flutter create bug`)
// Add above first_frame_cb():
// --- Repro: a second window whose FlView owns a second FlEngine. ---
static gboolean destroy_second_window(gpointer window) {
// Disposes the second FlView and with it the second FlEngine.
gtk_widget_destroy(GTK_WIDGET(window));
return G_SOURCE_REMOVE;
}
static gboolean redraw_first_window(gpointer window) {
// Any repaint of the remaining window triggers the crash (hovering or clicking
// works too); force one so the repro is deterministic.
gtk_widget_queue_draw(GTK_WIDGET(window));
return G_SOURCE_REMOVE;
}
// Add at the end of my_application_activate(), after gtk_widget_grab_focus(...):
// --- Repro: second window with its own engine, destroyed after 5 seconds. ---
GtkWindow* second =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
gtk_window_set_title(second, "second engine");
gtk_window_set_default_size(second, 400, 300);
g_autoptr(FlDartProject) second_project = fl_dart_project_new();
FlView* second_view = fl_view_new(second_project);
gtk_widget_show(GTK_WIDGET(second_view));
gtk_container_add(GTK_CONTAINER(second), GTK_WIDGET(second_view));
gtk_widget_show(GTK_WIDGET(second));
g_timeout_add_seconds(5, destroy_second_window, second);
g_timeout_add_seconds(6, redraw_first_window, window);lib/main.dart is the unmodified counter app.
Screenshots or Video
N/A
Logs
Logs (stderr, then gdb with a breakpoint on eglTerminate)
embedder.cc (2615): 'FlutterEngineRemoveView' returned 'kInvalidArguments'. Remove view info was invalid. The implicit view cannot be removed.
=== eglTerminate called, display 0x7fffe4004430
#0 eglTerminate () at /usr/lib/x86_64-linux-gnu/libEGL.so.1
#1 ?? () at .../bundle/lib/libflutter_linux_gtk.so
#2 g_object_unref () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#3 ?? () at .../bundle/lib/libflutter_linux_gtk.so
#4 g_object_unref () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#5 ?? () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#6 g_object_unref () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
(com.example.bug): Gdk-WARNING **: eglMakeCurrent failed
(com.example.bug): Gdk-WARNING **: eglMakeCurrent failed
(com.example.bug): Gdk-WARNING **: eglMakeCurrent failed
(com.example.bug): Gdk-WARNING **: eglMakeCurrent failed
(com.example.bug): Gdk-WARNING **: eglMakeCurrent failed
Thread 1 "bug" received signal SIGSEGV, Segmentation fault.
#0 ?? () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#1 ?? () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#2 gdk_window_end_draw_frame () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#3 gtk_main_do_event () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#4 ?? () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
...
#9 g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
...
#16 g_main_context_iteration () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#17 g_application_run () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#18 main ()Flutter Doctor output
Doctor output
[!] Flutter (Channel [user-branch], 3.47.7, on Ubuntu 26.04 LTS 7.0.0-29-generic, locale pt_BR.UTF-8)
! Flutter version 3.47.7 on channel [user-branch] at /home/user/dev/flutter
Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision abaf9c5237 (6 days ago), 2026-10-08 09:51:21 -0700
• Engine revision deb287481e
• Dart version 3.13.5
• DevTools version 2.60.0
[✗] Android toolchain - develop for Android devices
✗ cmdline-tools component is missing.
[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
[✓] Linux toolchain - develop for Linux desktop
• Ubuntu clang version 21.1.8 (6ubuntu1)
• cmake version 4.2.3
• ninja version 1.13.2
• pkg-config version 2.5.1
[✓] Connected device (1 available)
• Linux (desktop) • linux • linux-x64 • Ubuntu 26.04 LTS 7.0.0-29-generic
[✓] Network resources
• All expected network resources are available.The channel shows as [user-branch] because the SDK was cloned at the 3.47.7 stable tag.
Activity
suryaKommana2662 commentedon Oct 15, 2026
@rhpuppi Thanks for the report. Tested using the Chromebook Linux container. The application built and launched successfully, but graphics-related warnings were observed. The reported crash could not be confirmed in this environment. Routing to the
team-linuxfor further investigationflutter-triage-bot commentedon Oct 15, 2026
The
triaged-linuxlabel is irrelevant if there is noteam-linuxlabel orfyi-linuxlabel.robert-ancell commentedon Oct 16, 2026
Confirmed. This only occurs when you have multiple engines, the normal case of multiple views with one engine doesn't trigger this problem.
fix(linux): hide sub-windows instead of destroying them
Don't terminate the shared EGL display when an engine is disposed (fl…