After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 793062 - [Wayland] Crash under gdk_wayland_window_attach_image()
[Wayland] Crash under gdk_wayland_window_attach_image()
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Wayland
3.22.x
Other Linux
: Normal major
: ---
Assigned To: gtk-bugs
gtk-bugs
https://gitlab.gnome.org/GNOME/gtk/me...
Depends on:
Blocks:
 
 
Reported: 2018-01-31 12:26 UTC by Martin Stransky
Modified: 2018-03-27 08:37 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
[PATCH] gdkwindow: Do not generate expose event if not mapped (1.15 KB, patch)
2018-02-05 16:17 UTC, Olivier Fourdan
none Details | Review
[PATCH] gdkwindow: Don't paint if the window is unmapped (1.45 KB, patch)
2018-02-19 13:03 UTC, Olivier Fourdan
none Details | Review
[PATCH] wayland: Don't paint if the window is unmapped (1.19 KB, patch)
2018-02-20 09:46 UTC, Olivier Fourdan
none Details | Review

Description Martin Stransky 2018-01-31 12:26:34 UTC
Follow up from Bug 773274 comment 27.

The provided patch from https://bugzilla.gnome.org/attachment.cgi?id=367641&action=diff works as expected - the issue is fixed.
Comment 1 Martin Stransky 2018-01-31 12:58:15 UTC
I see another crash with this patch applied:

(gdb) p	impl->display_server.wl_surface
$2 = (struct wl_surface *) 0x0

It also comes from the expose event handler, bt:

  • #8 wl_surface_damage
    at /usr/include/wayland-client-protocol.h line 3478
  • #9 gdk_window_impl_wayland_end_paint
    at gdkwindow-wayland.c line 952
  • #10 gdk_window_end_paint_internal
    at gdkwindow.c line 3021
  • #11 gdk_window_end_draw_frame
    at gdkwindow.c line 3289
  • #12 gtk_widget_render
    at gtkwidget.c line 17522
  • #13 gtk_main_do_event
    at gtkmain.c line 1834
  • #14 _gdk_event_emit
    at gdkevents.c line 73
  • #15 _gdk_window_process_updates_recurse_helper
    at gdkwindow.c line 3852
  • #16 gdk_window_process_updates_internal
    at gdkwindow.c line 3998
  • #17 gdk_window_process_updates_with_mode
    at gdkwindow.c line 4192
  • #21 <emit signal ??? on instance 0x7f9f3fff2430 [GdkFrameClockIdle]>
    at gsignal.c line 3447
  • #22 _gdk_frame_clock_emit_paint
    at gdkframeclock.c line 640
  • #23 gdk_frame_clock_paint_idle
    at gdkframeclockidle.c line 430
  • #24 gdk_threads_dispatch
    at gdk.c line 743
  • #25 g_timeout_dispatch
    at gmain.c line 4615
  • #26 g_main_dispatch
    at gmain.c line 3142

Comment 2 Martin Stransky 2018-01-31 12:59:50 UTC
This crash happens at gdk_window_impl_wayland_end_paint() and at wl_surface_damage() where impl->display_server.wl_surface is null.
Comment 3 Olivier Fourdan 2018-01-31 17:04:13 UTC
I wonder how we can end up in end_paint() with a wl_surface being NULL.

_gdk_frame_clock_emit_paint() ends up calling gtk_widget_render() which calls gdk_window_end_draw_frame (window, context) which calls gdk_window_impl_wayland_end_paint(), but there the window's wl_surface is NULL.

As Martin pointed out, this is from:

1833     case GDK_EXPOSE:
1834       if (event->any.window)
1835         gtk_widget_render (event_widget, event->any.window, event->expose.region);
1836       break;

So the window here from event->any.window has its wl_surface NULL.

That event here comes from _gdk_window_process_updates_recurse_helper():

 3835   /* While gtk+ no longer handles exposes on anything but native
 3836      window we still have to send them to all windows that have the
 3837      event mask set for backwards compat. We also need to send
 3838      it to all native windows, even if they don't specify the
 3839      expose mask, because they may have non-native children that do. */
 3840   if (gdk_window_has_impl (window) ||
 3841       window->event_mask & GDK_EXPOSURE_MASK)
 3842     {
 3843       GdkEvent event;
 3844 
 3845       event.expose.type = GDK_EXPOSE;
 3846       event.expose.window = window; /* we already hold a ref */
 3847       event.expose.send_event = FALSE;
 3848       event.expose.count = 0;
 3849       event.expose.region = clipped_expose_region;
 3850       cairo_region_get_extents (clipped_expose_region, &event.expose.area);
 3851 
 3852       _gdk_event_emit (&event);
 3853     }
 3854 

And this is from gdk_window_process_updates_internal(window) called from:

 4163 static void
 4164 gdk_window_process_updates_with_mode (GdkWindow     *window,
 4165                                       int            recurse_mode)
 4166 {
 ...
 4174 
 4175   find_impl_windows_to_update (list, window, recurse_mode);
 4176 
 4177   if (window->impl_window != window)
 4178     g_ptr_array_add (list, g_object_ref (window->impl_window));
 4179 
 4180   for (i = (int)list->len - 1; i >= 0; i --)
 4181     {
 4182       GdkWindow *impl_window = g_ptr_array_index (list, i);
 4183 
 4184       if (impl_window->update_area &&
 4185           !impl_window->update_freeze_count &&
 4186           !gdk_window_is_toplevel_frozen (impl_window) &&
 4187 
 4188           /* Don't recurse into process_updates_internal, we'll
 4189            * do the update later when idle instead. */
 4190           !impl_window->in_update)
 4191         {
 4192           gdk_window_process_updates_internal (impl_window);
 4193           gdk_window_remove_update_window (impl_window);
 4194         }
 4195     }
Comment 4 Martin Stransky 2018-02-01 14:32:07 UTC
You can use this package to do the testing:

https://koji.fedoraproject.org/koji/buildinfo?buildID=1022923

it runs natively under Wayland.
Comment 5 Olivier Fourdan 2018-02-02 10:39:25 UTC
(In reply to Martin Stransky from comment #4)
> You can use this package to do the testing:
> 
> https://koji.fedoraproject.org/koji/buildinfo?buildID=1022923
> 
> it runs natively under Wayland.

Yeah, but it's hardly usable to be honest. I'm not even sure how to reproduce with it.
Comment 6 Martin Stransky 2018-02-02 10:50:05 UTC
(In reply to Olivier Fourdan from comment #5)
> (In reply to Martin Stransky from comment #4)
> > You can use this package to do the testing:
> > 
> > https://koji.fedoraproject.org/koji/buildinfo?buildID=1022923
> > 
> > it runs natively under Wayland.
> 
> Yeah, but it's hardly usable to be honest. I'm not even sure how to
> reproduce with it.

:) well only issue I'm aware of is missing clipboard selection (mouse middle button paste). If you see crashes it may be caused by this bug - you need to enable ABRT to catch the crashes probably or run the browser under gdb. Or is there anything else?
Comment 7 Olivier Fourdan 2018-02-02 10:55:58 UTC
Nope, no crash (yet), but it's hardly usable for me because all menus are truncated, missing most of the entries.

Seems like restarting FF has fixed it now... weird.
Comment 8 Olivier Fourdan 2018-02-02 16:06:38 UTC
OK, I managed to reproduce a couple of times (every time that occured while switching back to the FF window, when it changes from “unfocused” to “focused” state)  and take a closer look at hte GdkWindow being “end-painted”:

gdb) p *window
$1 = {parent_instance = {g_type_instance = {g_class = 0x7ffff6a6b6b0}, ref_count = 10, qdata = 0x7fffb60d3580}, 
  impl = 0x7fffb6f09400 [GdkWindowImplWayland], parent = 0x7ffff6abf050 [GdkWaylandWindow], transient_for = 0x7fffcf0f1250 [GdkWaylandWindow], 
  visual = 0x7ffff6abd180 [GdkWaylandVisual], user_data = 0x7fffb6f09260, x = 238, y = 101, event_mask = 6553366, window_type = 3 '\003', 
  depth = 32 ' ', resize_count = 0 '\000', toplevel_window_type = -1 '\377', filters = 0x0, children = 0x7fffb799c630 = {0x7fffb799c5d0}, 
  children_list_node = {data=0x7fffb799c440, next=0x7fffac145310, prev=0x7fffb799c950}, native_children = 0x0, background = 0x7fffabe11060, 
  current_paint = {surface = 0x7fffacdf2b00, region = 0x7fffb610fd00, flushed_region = 0x7fffb63702e0, need_blend_region = 0x7fffb6370300, 
    surface_needs_composite = 0, use_gl = 0}, gl_paint_context = 0x0, update_area = 0x0, update_freeze_count = 0, 
  active_update_area = 0x7fffb610f0e0, old_updated_area = {0x0, 0x0}, old_state = GDK_WINDOW_STATE_FOCUSED, 
  state = (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_FOCUSED), alpha = 255 '\377', fullscreen_mode = 0 '\000', input_only = 0, 
  pass_through = 0, modal_hint = 0, composited = 0, has_alpha_background = 0, destroyed = 0, accept_focus = 1, focus_on_map = 1, shaped = 0, 
  support_multidevice = 0, synthesize_crossing_event_queued = 1, effective_visibility = 3, visibility = 2, native_visibility = 0, viewable = 0, 
  applied_shape = 0, in_update = 1, geometry_dirty = 1, event_compression = 1, frame_clock_events_paused = 0, 
  impl_window = 0x7fffb799c440 [GdkWaylandWindow], update_and_descendants_freeze_count = 0, abs_x = 0, abs_y = 0, width = 314, height = 200, 
  shadow_top = 0, shadow_left = 0, shadow_right = 0, shadow_bottom = 0, num_offscreen_children = 0, clip_region = 0x7fffb6370720, cursor = 0x0, 
  device_cursor = 0x7fffabe249a0, shape = 0x0, input_shape = 0x0, devices_inside = 0x0, device_events = 0x0, source_event_masks = 0x0, 
  device_added_handler_id = 0, device_changed_handler_id = 0, frame_clock = 0x7fffabad3cb0 [GdkFrameClockIdle], invalidate_handler = 0x0, 
  drawing_context = 0x7fffb84358e0 [GdkDrawingContext], opaque_region = 0x0}

(gdb) p (GdkWindowImplWayland) *window->impl
$2 = {parent_instance = {parent = {g_type_instance = {g_class = 0x7ffff6a19c00}, ref_count = 3, qdata = 0x0}}, 
  wrapper = 0x7fffb799c440 [GdkWaylandWindow], display_server = {outputs = 0x0, wl_surface = 0x0, xdg_surface = 0x0, xdg_toplevel = 0x0, 
    xdg_popup = 0x0, gtk_surface = 0x0, wl_subsurface = 0x0, egl_window = 0x0, dummy_egl_window = 0x0, xdg_exported = 0x0, 
    server_decoration = 0x0}, egl_surface = 0x0, dummy_egl_surface = 0x0, initial_configure_received = 0, mapped = 0, use_custom_surface = 0, 
  pending_buffer_attached = 0, pending_commit = 0, awaiting_frame = 0, hint = GDK_WINDOW_TYPE_HINT_UTILITY, 
  transient_for = 0x7fffcf0f1250 [GdkWaylandWindow], popup_parent = 0x0, position_method = POSITION_METHOD_MOVE_RESIZE, 
  staging_cairo_surface = 0x7fffacdf2b00, committed_cairo_surface = 0x0, backfill_cairo_surface = 0x0, pending_buffer_offset_x = 0, 
  pending_buffer_offset_y = 0, title = 0x7fffabf4c4b0 "Firefox", application = {was_set = 0, application_id = 0x0, app_menu_path = 0x0, 
    menubar_path = 0x0, window_object_path = 0x0, application_object_path = 0x0, unique_bus_name = 0x0}, geometry_hints = {min_width = 1, 
    min_height = 2, max_width = 32767, max_height = 32767, base_width = 1, base_height = 2, width_inc = 13, height_inc = 0, 
    min_aspect = 6.9533024459871814e-310, max_aspect = 0, win_gravity = GDK_GRAVITY_NORTH_WEST}, 
  geometry_mask = (GDK_HINT_POS | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | GDK_HINT_WIN_GRAVITY), grab_input_seat = 0x0, 
  pending_frame_counter = 0, scale = 1, margin_left = 0, margin_right = 0, margin_top = 0, margin_bottom = 0, margin_dirty = 0, 
  initial_fullscreen_monitor = -1, opaque_region = 0x0, opaque_region_dirty = 1, input_region = 0x0, input_region_dirty = 1, 
  staged_updates_region = 0x0, saved_width = -1, saved_height = -1, parent_surface_committed_handler = 0, pending_move_to_rect = {rect = {x = 0, 
      y = 0, width = 0, height = 0}, rect_anchor = 0, window_anchor = 0, anchor_hints = 0, rect_anchor_dx = 0, rect_anchor_dy = 0}, pending = {
    width = 0, height = 0, state = (unknown: 0)}, exported = {handle = 0x0, export_count = 0, closures = 0x0, idle_source_id = 0}, 
  imported_transient_for = 0x0, shortcuts_inhibitors = 0x7fffabe24a00 = {[0x621] = 0x621}}
Comment 9 Ray Strode [halfline] 2018-02-02 16:29:23 UTC
that's a weird combo:

state = (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_FOCUSED)
Comment 10 Olivier Fourdan 2018-02-02 16:33:18 UTC
“old_state = GDK_WINDOW_STATE_FOCUSED, state = (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_FOCUSED)” seems weird, how can a window be withdrawn and focused?

Another weird thing is:

display_server = {outputs = 0x0, wl_surface = 0x0, xdg_surface = 0x0, xdg_toplevel = 0x0, xdg_popup = 0x0, gtk_surface = 0x0, wl_subsurface = 0x0, egl_window = 0x0, dummy_egl_window = 0x0, xdg_exported = 0x0, server_decoration = 0x0}, egl_surface = 0x0, dummy_egl_surface = 0x0, initial_configure_received = 0, mapped = 0, use_custom_surface = 0, pending_buffer_attached = 0, pending_commit = 0, awaiting_frame = 0

All values are 0, as if the surface was withdrawn.

Also hint = GDK_WINDOW_TYPE_HINT_UTILITY,

This comes from Firefox code:

3517 nsresult
3518 nsWindow::Create(nsIWidget* aParent,
3519                  nsNativeWidget aNativeParent,
3520                  const LayoutDeviceIntRect& aRect,
3521                  nsWidgetInitData* aInitData)
3522 {
...
3690                 switch (aInitData->mPopupHint) {
3691                     case ePopupTypeMenu:
3692                         // Use GDK_WINDOW_TYPE_HINT_UTILITY on Wayland which
3693                         // guides Gtk to create the popup as subsurface
3694                         // instead of xdg_shell popup (see Bug 1423598).
3695                         gtkTypeHint = mIsX11Display ? GDK_WINDOW_TYPE_HINT_POPUP_MENU :
3696                                                       GDK_WINDOW_TYPE_HINT_UTILITY;

So the window causing this issue would be a “ePopupTypeMenu”.
Comment 11 Olivier Fourdan 2018-02-05 16:17:56 UTC
Created attachment 367922 [details] [review]
[PATCH] gdkwindow: Do not generate expose event if not mapped

If a window is not mapped, we shouldn't be generating fake expose
events, that can causes crashes further down the tree with Wayland when
not using GL.
Comment 12 Olivier Fourdan 2018-02-05 16:18:21 UTC
Can you try with this patch?
Comment 13 Olivier Fourdan 2018-02-06 08:38:32 UTC
FWIW, I've been running with this patch since yesterday and had no crash in gdk Wayland code since then.

Not surprising, if the window is withdrawn, the Wayland resources are NULL (what the see in the GdkWindowImplWayland in comment 8), so by not generating expose events when the window is withdrawn (attachment 367922 [details] [review]), we avoid the crash.

Yet, I wonder if Firefox is not leaking Wayland resources somehow, I left it running overnight and today my entire system started to crawl, with ram and swap up to 90% (the system has 12Gb or RAM) and gnome-shell taking most of that.

Killing Firefox freed a large part of the memory used by gnome-shell, so I suspect Firefox might be leaking resources.

However I don't think the leak is caused by the patch (attachment 367922 [details] [review]), but it might be the same root cause.
Comment 14 Martin Stransky 2018-02-12 12:02:52 UTC
I'll check that patch, Thanks. The leaking is interesting, I'll check that.
Comment 15 Olivier Fourdan 2018-02-12 12:17:56 UTC
I am not 100% sure about the leak, I've left FF running a few times overnight and that did not happen.

The patch fixes the issue, I reckon.
Comment 16 Martin Stransky 2018-02-14 08:43:07 UTC
With the latest patch applied I still see a crash:

  • #6 <signal handler called>
  • #7 wl_proxy_marshal
    at src/wayland-client.c line 692
  • #8 wl_surface_damage
    at /usr/include/wayland-client-protocol.h line 3478
  • #9 gdk_window_impl_wayland_end_paint
    at gdkwindow-wayland.c line 952
  • #10 gdk_window_end_paint_internal
    at gdkwindow.c line 3021
  • #11 gdk_window_end_draw_frame
    at gdkwindow.c line 3289
  • #12 gtk_widget_render
    at gtkwidget.c line 17522
  • #13 gtk_main_do_event
    at gtkmain.c line 1834
  • #14 _gdk_event_emit
    at gdkevents.c line 73
  • #15 _gdk_window_process_updates_recurse_helper
    at gdkwindow.c line 3853
  • #16 _gdk_window_process_updates_recurse
    at gdkwindow.c line 3910
  • #17 gdk_window_impl_process_updates_recurse
    at gdkwindowimpl.c line 333
  • #18 gdk_window_process_updates_internal
    at gdkwindow.c line 3999
  • #19 gdk_window_process_updates_with_mode
    at gdkwindow.c line 4193
  • #20 gdk_window_paint_on_clock
    at gdkwindow.c line 11700
  • #24 <emit signal ??? on instance 0x7fccc7d2d860 [GdkFrameClockIdle]>
    at gsignal.c line 3447
  • #25 _gdk_frame_clock_emit_paint
    at gdkframeclock.c line 640
  • #26 gdk_frame_clock_paint_idle
    at gdkframeclockidle.c line 430

it comes from expose event.

(gdb) p* window
$3 = {
  parent_instance = {
    g_type_instance = {
      g_class = 0x7fcd1cd616b0
    }, 
    ref_count = 11, 
    qdata = 0x7fcce02d9780
  }, 
  impl = 0x7fcce91d9000 [GdkWindowImplWayland], 
  parent = 0x7fcd1cdbe050 [GdkWaylandWindow], 
  transient_for = 0x7fcce977c5d0 [GdkWaylandWindow], 
  visual = 0x7fcd1cdb6440 [GdkWaylandVisual], 
  user_data = 0x7fcce896fe60, 
  x = 23, 
  y = 88, 
  event_mask = 6553366, 
  window_type = 3 '\003', 
  depth = 32 ' ', 
  resize_count = 0 '\000', 
  toplevel_window_type = -1 '\377', 
  filters = 0x0, 
  children = 0x7fcce96f7b40 = {0x7fcce96f7ae0}, 
  children_list_node = {data=0x7fcce96f7950, next=0x7fcce96f7500, prev=0x0}, 
  native_children = 0x0, 
  background = 0x7fccc8743d40, 
  current_paint = {
    surface = 0x7fccc7d51980, 
    region = 0x7fccf54172a0, 
    flushed_region = 0x7fccf54172e0, 
    need_blend_region = 0x7fccf54173e0, 
    surface_needs_composite = 0, 
    use_gl = 0
  }, 
  gl_paint_context = 0x0, 
  update_area = 0x0, 
  update_freeze_count = 0, 
  active_update_area = 0x7fccea6fcb40, 
  old_updated_area = {0x0, 0x0}, 
  old_state = GDK_WINDOW_STATE_FOCUSED, 
  state = (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_FOCUSED), 
  alpha = 255 '\377', 
  fullscreen_mode = 0 '\000', 
  input_only = 0, 
  pass_through = 0, 
  modal_hint = 0, 
  composited = 0, 
  has_alpha_background = 0, 
  destroyed = 0, 
  accept_focus = 1, 
  focus_on_map = 1, 
  shaped = 0, 
  support_multidevice = 0, 
  synthesize_crossing_event_queued = 1, 
  effective_visibility = 3, 
  visibility = 2, 
  native_visibility = 0, 
  viewable = 0, 
  applied_shape = 0, 
  in_update = 1, 
  geometry_dirty = 1, 
  event_compression = 1, 
  frame_clock_events_paused = 0, 
  impl_window = 0x7fcce96f7950 [GdkWaylandWindow], 
  update_and_descendants_freeze_count = 0, 
  abs_x = 0, 
  abs_y = 0, 
  width = 1185, 
  height = 113, 
  shadow_top = 0, 
  shadow_left = 0, 
  shadow_right = 0, 
  shadow_bottom = 0, 
  num_offscreen_children = 0, 
  clip_region = 0x7fccf54177c0, 
  cursor = 0x0, 
  device_cursor = 0x7fccdae657c0 = {
    [0x5e1] = 0x5e1
  }, 
  shape = 0x0, 
  input_shape = 0x0, 
  devices_inside = 0x0, 
  device_events = 0x0, 
  source_event_masks = 0x0, 
  device_added_handler_id = 0, 
  device_changed_handler_id = 0, 
  frame_clock = 0x7fccc7d2d860 [GdkFrameClockIdle], 
  invalidate_handler = 0x0, 
  drawing_context = 0x7fcce00eab80 [GdkDrawingContext], 
  opaque_region = 0x0
}
Comment 17 Martin Stransky 2018-02-14 08:52:45 UTC
I can 100% reproducible with the firefox-59 build I provide. Navigate to url bar and type "about:addons" there. When awesomebar disappears FF crashes.
Comment 18 Olivier Fourdan 2018-02-14 09:33:44 UTC
(In reply to Martin Stransky from comment #16)
> With the latest patch applied I still see a crash:

Weird. Can you double-check the version you use is the one with the patch?

Reason I ask is because the backtrace in comment #16 shows:

 #15 _gdk_window_process_updates_recurse_helper
 at gdkwindow.c line 3853

with:

 state = (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_FOCUSED)

However the patch calls the _gdk_event_emit() only if GDK_WINDOW_IS_MAPPED(window).

GDK_WINDOW_IS_MAPPED() is defined as:

  #define GDK_WINDOW_IS_MAPPED(window) (((window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)

So with the patch applied you cannot get to frame #15 with “state = (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_FOCUSED)”

(In reply to Martin Stransky from comment #17)
> I can 100% reproducible with the firefox-59 build I provide. Navigate to url
> bar and type "about:addons" there. When awesomebar disappears FF crashes.

Not here, with the patch applied, it works.
Comment 19 Martin Stransky 2018-02-14 09:39:27 UTC
(In reply to Olivier Fourdan from comment #18)
> (In reply to Martin Stransky from comment #16)
> > With the latest patch applied I still see a crash:
> 
> Weird. Can you double-check the version you use is the one with the patch?

Yes, I checked it again. I use my own custom build with the patch, I checked package build log and the patch is applied. It also contains the first patch.
Comment 20 Olivier Fourdan 2018-02-14 09:51:15 UTC
(In reply to Martin Stransky from comment #19)
> Yes, I checked it again. I use my own custom build with the patch, I checked
> package build log and the patch is applied. It also contains the first patch.

First patch should not be needed, only attachment 367922 [details] [review] 

But if you get to comment 16 with attachment 367922 [details] [review], then this sounds like a multi-thread issue, /something/ changes the Gdkindow state between the test GDK_WINDOW_IS_MAPPED() and the _gdk_event_emit() in frame 15, otherwise I don't see how that's possible.
Comment 21 Olivier Fourdan 2018-02-14 09:56:59 UTC
FWIW, the code in gdk/gdkwindow.c with the patch applied should read as:

 3802 static void
 3803 _gdk_window_process_updates_recurse_helper (GdkWindow *window,
 3804                                             cairo_region_t *expose_region)
 3805 {
 ...
 3835   /* While gtk+ no longer handles exposes on anything but native
 3836      window we still have to send them to all windows that have the
 3837      event mask set for backwards compat. We also need to send
 3838      it to all native windows, even if they don't specify the
 3839      expose mask, because they may have non-native children that do. */
 3840   if (GDK_WINDOW_IS_MAPPED(window) &&
 3841       (gdk_window_has_impl (window) ||
 3842        window->event_mask & GDK_EXPOSURE_MASK))
 3843     {
 3844       GdkEvent event;
 3845 
 3846       event.expose.type = GDK_EXPOSE;
 3847       event.expose.window = window; /* we already hold a ref */
 3848       event.expose.send_event = FALSE;
 3849       event.expose.count = 0;
 3850       event.expose.region = clipped_expose_region;
 3851       cairo_region_get_extents (clipped_expose_region, &event.expose.area);
 3852 
 3853       _gdk_event_emit (&event);
 3854     }
 3855 

So we should not get to _gdk_event_emit() line 3853 with “state = (GDK_WINDOW_STATE_WITHDRAWN | GDK_WINDOW_STATE_FOCUSED)” because we're within “if (GDK_WINDOW_IS_MAPPED(window) && ...) { }” line 3840
Comment 22 Olivier Fourdan 2018-02-15 08:23:37 UTC
Reproduced as well...
Comment 23 Martin Stransky 2018-02-15 09:44:06 UTC
It may be useful to run Firefox under rr (http://rr-project.org/) and check how exactly that happens.
Comment 24 Olivier Fourdan 2018-02-19 09:14:11 UTC
So I think what happens and I believe this is Firefox doing something unexpected.

The issue occurs because the window we're updating recursively is being unmapped (on Wayland if you unmap a window, it's surface resource is destroyed).

The patch (attachment 367922 [details] [review]) I posted checks for the window being mapped prior to calling the update, and that patch doesn't fix the issue, which means that when we checked, the window was mapped. When we crash, it's not mapped anymore, so “something” is unmapping the window while gdk is updating it recursively. Some tests shows this is not a threding issue, the crash and the unmap occur from within the same thread id.

Unfortunately using a simple break in gdb on gdk_window_unmap() is not practical so the solution is to add a variable, increase its value prior to enter the recursion and check for its value when unmapping the window, so that we can tell exactly when the window is being unmapped from within the recursion.

That leads to the following backtrace:

    (gdb) bt
    #0  mozalloc_abort (msg=msg@entry=0x55555557d6d8 "Redirecting call to abort() to mozalloc_abort\n")
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/memory/mozalloc/mozalloc_abort.cpp:33
    #1  0x00005555555668b0 in abort () at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/memory/mozalloc/mozalloc_abort.cpp:80
    #2  0x00007fffef81aa85 in g_assertion_message (domain=domain@entry=0x7ffff43a140e "Gdk", 
        file=file@entry=0x7ffff43b8ee8 "/home/ofourdan/src/gnome/gtk+-3/gdk/gdkwindow.c", line=line@entry=5667, 
        func=func@entry=0x7ffff43ba3e0 <__func__.66322> "gdk_window_hide", 
        message=message@entry=0x7fffaad8ae50 "assertion failed: (recurse_level == 0)") at /home/ofourdan/src/gnome/glib/glib/gtestutils.c:2532
    #3  0x00007fffef81aada in g_assertion_message_expr (domain=domain@entry=0x7ffff43a140e "Gdk", 
        file=file@entry=0x7ffff43b8ee8 "/home/ofourdan/src/gnome/gtk+-3/gdk/gdkwindow.c", line=line@entry=5667, 
        func=func@entry=0x7ffff43ba3e0 <__func__.66322> "gdk_window_hide", expr=expr@entry=0x7ffff43b8e6a "recurse_level == 0")
        at /home/ofourdan/src/gnome/glib/glib/gtestutils.c:2555
 →  #4  0x00007ffff43558b0 in gdk_window_hide (window=0x7fffab257760) at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkwindow.c:5667
    #5  0x00007fffe973be90 in moz_container_unmap (widget=0x7fffaa3319b0)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/gtk/mozcontainer.cpp:337
    #6  0x00007fffefcd57d0 in _g_closure_invoke_va (closure=0x7ffff6afb420, return_value=0x0, instance=0x7fffaa3319b0, args=0x7fffffff9fe8, 
        n_params=0, param_types=0x0) at /home/ofourdan/src/gnome/glib/gobject/gclosure.c:867
    #7  0x00007fffefcf133e in g_signal_emit_valist (instance=0x7fffaa3319b0, signal_id=<optimized out>, detail=0, 
        var_args=var_args@entry=0x7fffffff9fe8) at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3300
    #8  0x00007fffefcf1802 in g_signal_emit (instance=instance@entry=0x7fffaa3319b0, signal_id=<optimized out>, detail=detail@entry=0)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3447
 →  #9  0x00007ffff495c24c in gtk_widget_unmap (widget=0x7fffaa3319b0) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwidget.c:5033
    #10 0x00007fffefcd568d in g_closure_invoke (closure=0x7ffff6afb420, return_value=0x0, n_param_values=1, param_values=0x7fffffffa2a0, 
        invocation_hint=0x7fffffffa240) at /home/ofourdan/src/gnome/glib/gobject/gclosure.c:804
    #11 0x00007fffefce878e in signal_emit_unlocked_R (node=node@entry=0x7ffff6affb80, detail=detail@entry=0, instance=instance@entry=0x7fffaa908a60, 
        emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffa2a0)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3565
    #12 0x00007fffefcf0f35 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, 
        var_args=var_args@entry=0x7fffffffa448) at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3391
    #13 0x00007fffefcf1802 in g_signal_emit (instance=instance@entry=0x7fffaa908a60, signal_id=<optimized out>, detail=detail@entry=0)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3447
    #14 0x00007ffff495c24c in gtk_widget_unmap (widget=0x7fffaa908a60) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwidget.c:5033
    #15 0x00007ffff4970e8c in gtk_window_hide (widget=0x7fffaa908a60) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwindow.c:6217
    #16 0x00007fffefcd568d in g_closure_invoke (closure=0x7ffff6afb3a0, return_value=0x0, n_param_values=1, param_values=0x7fffffffa720, 
        invocation_hint=0x7fffffffa6c0) at /home/ofourdan/src/gnome/glib/gobject/gclosure.c:804
    #17 0x00007fffefce878e in signal_emit_unlocked_R (node=node@entry=0x7ffff6affac0, detail=detail@entry=0, instance=instance@entry=0x7fffaa908a60, 
        emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffa720)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3565
    #18 0x00007fffefcf0f35 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, 
        var_args=var_args@entry=0x7fffffffa8c8) at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3391
    #19 0x00007fffefcf1802 in g_signal_emit (instance=instance@entry=0x7fffaa908a60, signal_id=<optimized out>, detail=detail@entry=0)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3447
    #20 0x00007ffff4964235 in gtk_widget_hide (widget=0x7fffaa908a60) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwidget.c:4901
    #21 0x00007fffe97160b3 in nsWindow::NativeShow (this=0x7fffaa908400, aAction=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/gtk/nsWindow.cpp:4232
    #22 0x00007fffe96d2af4 in nsView::DoResetWidgetBounds (this=<optimized out>, aMoveOnly=<optimized out>, aInvalidateChangedSize=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/view/nsView.cpp:341
    #23 0x00007fffe96d5fba in nsViewManager::ProcessPendingUpdatesForView (this=this@entry=0x7fffc14c5fc0, aView=<optimized out>, 
        aFlushDirtyRegion=aFlushDirtyRegion@entry=true) at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/view/nsViewManager.cpp:399
    #24 0x00007fffe96d61a5 in nsViewManager::ProcessPendingUpdates (this=this@entry=0x7fffc14c5fc0)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/view/nsViewManager.cpp:1102
    #25 0x00007fffe96d62d8 in nsViewManager::WillPaintWindow (this=this@entry=0x7fffc14c5fc0, aWidget=0x7fffaa908400)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/view/nsViewManager.cpp:707
    #26 0x00007fffe96d6326 in nsView::WillPaintWindow (this=<optimized out>, aWidget=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/view/nsView.cpp:1059
 →  #27 0x00007fffe9722c0b in nsWindow::OnExposeEvent (this=<optimized out>, cr=<optimized out>, this=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/gtk/nsWindow.cpp:2089
    #28 0x00007fffe97239b2 in draw_window_of_widget (widget=widget@entry=0x7fffaa3319b0, aWindow=0x7fffab257760, cr=cr@entry=0x7fffc9d42800)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/gtk/nsWindow.cpp:5455
    #29 0x00007fffe9723a0f in expose_event_cb (widget=widget@entry=0x7fffaa3319b0, cr=0x7fffc9d42800)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/gtk/nsWindow.cpp:5478
    #30 0x00007ffff481db4b in _gtk_marshal_BOOLEAN__BOXED (closure=closure@entry=0x7fffaa3fef80, return_value=return_value@entry=0x7fffffffaf20, 
        n_param_values=n_param_values@entry=2, param_values=param_values@entry=0x7fffffffafd0, invocation_hint=invocation_hint@entry=0x7fffffffaf70, 
        marshal_data=marshal_data@entry=0x0) at gtkmarshalers.c:83
    #31 0x00007ffff495949f in gtk_widget_draw_marshaller (closure=0x7fffaa3fef80, return_value=0x7fffffffaf20, n_param_values=2, 
        param_values=0x7fffffffafd0, invocation_hint=0x7fffffffaf70, marshal_data=0x0) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwidget.c:945
    #32 0x00007fffefcd568d in g_closure_invoke (closure=0x7fffaa3fef80, return_value=0x7fffffffaf20, n_param_values=2, param_values=0x7fffffffafd0, 
        invocation_hint=0x7fffffffaf70) at /home/ofourdan/src/gnome/glib/gobject/gclosure.c:804
    #33 0x00007fffefce86be in signal_emit_unlocked_R (node=<optimized out>, detail=detail@entry=0, instance=instance@entry=0x7fffaa3319b0, 
        emission_return=emission_return@entry=0x7fffffffb0d0, instance_and_params=instance_and_params@entry=0x7fffffffafd0)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3635
    #34 0x00007fffefcf091c in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, 
        var_args=var_args@entry=0x7fffffffb188) at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3401
    #35 0x00007fffefcf1802 in g_signal_emit (instance=instance@entry=0x7fffaa3319b0, signal_id=<optimized out>, detail=detail@entry=0)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3447
    #36 0x00007ffff4965ab2 in gtk_widget_draw_internal (widget=widget@entry=0x7fffaa3319b0, cr=cr@entry=0x7fffc9d42800, 
        clip_to_size=clip_to_size@entry=1) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwidget.c:7019
    #37 0x00007ffff475c202 in gtk_container_propagate_draw (container=container@entry=0x7fffaa908a60, child=0x7fffaa3319b0, 
        cr=cr@entry=0x7fffc9d42800) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkcontainer.c:3838
    #38 0x00007ffff475c2c2 in gtk_container_draw (widget=0x7fffaa908a60, cr=0x7fffc9d42800)
        at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkcontainer.c:3658
    #39 0x00007ffff4972dff in gtk_window_draw (widget=0x7fffaa908a60, cr=0x7fffc9d42800) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwindow.c:10401
    #40 0x00007ffff496586f in gtk_widget_draw_internal (widget=0x7fffaa908a60, cr=0x7fffc9d42800, clip_to_size=<optimized out>)
        at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwidget.c:7026
    #41 0x00007ffff496e763 in gtk_widget_render (widget=widget@entry=0x7fffaa908a60, window=0x7fffab2575d0, region=<optimized out>)
        at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkwidget.c:17536
    #42 0x00007ffff481cac1 in gtk_main_do_event (event=<optimized out>) at /home/ofourdan/src/gnome/gtk+-3/gtk/gtkmain.c:1838
    #43 0x00007ffff433d565 in _gdk_event_emit (event=event@entry=0x7fffffffb520) at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkevents.c:73
 →  #44 0x00007ffff434da8e in _gdk_window_process_updates_recurse_helper (window=0x7fffab2575d0, expose_region=<optimized out>)
        at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkwindow.c:3858
 →  #45 0x00007ffff434e670 in _gdk_window_process_updates_recurse (window=<optimized out>, expose_region=<optimized out>)
        at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkwindow.c:3917
    #46 0x00007ffff434e426 in gdk_window_process_updates_internal (window=0x7fffab2575d0) at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkwindow.c:4007
    #47 0x00007ffff434e620 in gdk_window_process_updates_with_mode (window=<optimized out>, recurse_mode=<optimized out>)
        at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkwindow.c:4201
    #48 0x00007fffefcd568d in g_closure_invoke (closure=0x7fffaa3fe620, return_value=0x0, n_param_values=1, param_values=0x7fffffffb800, 
        invocation_hint=0x7fffffffb7a0) at /home/ofourdan/src/gnome/glib/gobject/gclosure.c:804
    #49 0x00007fffefce86be in signal_emit_unlocked_R (node=node@entry=0x7ffff6aca9a0, detail=detail@entry=0, instance=instance@entry=0x7fffaa380ed0, 
        emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffb800)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3635
    #50 0x00007fffefcf0f35 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, 
        var_args=var_args@entry=0x7fffffffb9a8) at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3391
    #51 0x00007fffefcf1802 in g_signal_emit (instance=instance@entry=0x7fffaa380ed0, signal_id=<optimized out>, detail=detail@entry=0)
        at /home/ofourdan/src/gnome/glib/gobject/gsignal.c:3447
    #52 0x00007ffff4345f1f in _gdk_frame_clock_emit_paint (frame_clock=frame_clock@entry=0x7fffaa380ed0)
        at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkframeclock.c:640
    #53 0x00007ffff4346621 in gdk_frame_clock_paint_idle (data=0x7fffaa380ed0) at /home/ofourdan/src/gnome/gtk+-3/gdk/gdkframeclockidle.c:430
    #54 0x00007ffff4332140 in gdk_threads_dispatch (data=data@entry=0x7fffafdcb640) at /home/ofourdan/src/gnome/gtk+-3/gdk/gdk.c:743
    #55 0x00007fffef7f535d in g_timeout_dispatch (source=0x7fffb58bb4a0, callback=0x7ffff4332120 <gdk_threads_dispatch>, user_data=0x7fffafdcb640)
        at /home/ofourdan/src/gnome/glib/glib/gmain.c:4650
    #56 0x00007fffef7f4937 in g_main_dispatch (context=0x7ffff6a25be0) at /home/ofourdan/src/gnome/glib/glib/gmain.c:3177
    #57 g_main_context_dispatch (context=context@entry=0x7ffff6a25be0) at /home/ofourdan/src/gnome/glib/glib/gmain.c:3830
    #58 0x00007fffef7f4ca8 in g_main_context_iterate (context=context@entry=0x7ffff6a25be0, block=block@entry=0, dispatch=dispatch@entry=1, 
        self=<optimized out>) at /home/ofourdan/src/gnome/glib/glib/gmain.c:3903
    #59 0x00007fffef7f4d2c in g_main_context_iteration (context=0x7ffff6a25be0, context@entry=0x0, may_block=0)
        at /home/ofourdan/src/gnome/glib/glib/gmain.c:3964
    #60 0x00007fffe9732d3f in nsAppShell::ProcessNextNativeEvent (this=<optimized out>, mayWait=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/gtk/nsAppShell.cpp:295
    ---Type <return> to continue, or q <return> to quit---
    #61 0x00007fffe96ffb42 in nsBaseAppShell::DoProcessNextNativeEvent (this=this@entry=0x7fffd2b84040, mayWait=mayWait@entry=false)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/nsBaseAppShell.cpp:139
    #62 0x00007fffe96ffd7c in nsBaseAppShell::OnProcessNextEvent (this=0x7fffd2b84040, thr=0x7fffdc21c480, mayWait=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/nsBaseAppShell.cpp:272
    #63 0x00007fffe7746525 in nsThread::ProcessNextEvent (this=<optimized out>, aMayWait=<optimized out>, aResult=0x7fffffffbda7, 
        this=<optimized out>) at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/xpcom/threads/nsThread.cpp:952
    #64 0x00007fffe774f6d8 in NS_ProcessNextEvent (aThread=<optimized out>, aThread@entry=0x7fffdc21c480, aMayWait=aMayWait@entry=false)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/xpcom/threads/nsThreadUtils.cpp:517
    #65 0x00007fffe7b7859a in mozilla::ipc::MessagePump::Run (this=0x7fffdc2550c0, aDelegate=0x7fffdc254040)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/ipc/glue/MessagePump.cpp:97
    #66 0x00007fffe7b4de20 in MessageLoop::RunInternal (this=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/ipc/chromium/src/base/message_loop.cc:326
    #67 MessageLoop::RunHandler (this=<optimized out>) at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/ipc/chromium/src/base/message_loop.cc:319
    #68 MessageLoop::Run (this=<optimized out>) at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/ipc/chromium/src/base/message_loop.cc:299
    #69 0x00007fffe96fad38 in nsBaseAppShell::Run (this=0x7fffd2b84040) at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/widget/nsBaseAppShell.cpp:157
    #70 0x00007fffea5cdd2e in nsAppStartup::Run (this=0x7fffd351eb50)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/toolkit/components/startup/nsAppStartup.cpp:288
    #71 0x00007fffea666c3b in XREMain::XRE_mainRun (this=this@entry=0x7fffffffc030)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/toolkit/xre/nsAppRunner.cpp:4710
    #72 0x00007fffea667ae6 in XREMain::XRE_main (this=this@entry=0x7fffffffc030, argc=argc@entry=1, argv=argv@entry=0x7fffffffd358, aConfig=...)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/toolkit/xre/nsAppRunner.cpp:4849
    #73 0x00007fffea667e52 in XRE_main (argc=1, argv=0x7fffffffd358, aConfig=...)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/toolkit/xre/nsAppRunner.cpp:4941
    #74 0x0000555555559d1c in do_main (argc=1, argv=0x7fffffffd358, envp=<optimized out>)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/browser/app/nsBrowserApp.cpp:231
    #75 0x0000555555559489 in main (argc=1, argv=0x7fffffffd358, envp=0x7fffffffd368)
        at /usr/src/debug/firefox-59.0-0.6.fc27.x86_64/browser/app/nsBrowserApp.cpp:304
    (gdb) info threads

What this shows is that Firefox is unmapping the window on expose events (step #27), and an expose event is precisely what's emitted to update the content.

So basically, Firefox is unmapping the window while we're updating it, which leads to the crash.
Comment 25 Martin Stransky 2018-02-19 09:38:06 UTC
Olivier, thanks for looking at it.
Comment 26 Olivier Fourdan 2018-02-19 13:03:26 UTC
Created attachment 368558 [details] [review]
[PATCH] gdkwindow: Don't paint if the window is unmapped

I don't know if unmapping a toplevel window on expose events is legit or not (I would leave that to gtk+ devs to decide), but in case it's deemed as legit, the attached patch would avoid the crash.
Comment 27 Martin Stransky 2018-02-20 09:07:20 UTC
(In reply to Olivier Fourdan from comment #26)
> Created attachment 368558 [details] [review] [review]
> [PATCH] gdkwindow: Don't paint if the window is unmapped
> 
> I don't know if unmapping a toplevel window on expose events is legit or not
> (I would leave that to gtk+ devs to decide), but in case it's deemed as
> legit, the attached patch would avoid the crash.

Would be great to have the patch checked-in. A fix at Firefox side would need to rework complete popup window management.
Comment 28 Olivier Fourdan 2018-02-20 09:31:13 UTC
In that case it would be better to fix the issue in the Wayland backend, I reckon, as this is less likely to break other backends.

At least we now know exactly what happens and why it crashes.
Comment 29 Olivier Fourdan 2018-02-20 09:46:32 UTC
Created attachment 368612 [details] [review]
[PATCH] wayland: Don't paint if the window is unmapped

This patch is better, IMHO, it checks for the window being mapped in the gdkwayland backend where it actually matters (because on Wayland, the surface and other resources are released when unmapped), so we don't interfere with the regular gdk update processing (and thus we avoid gdk warnings about paint operations already in progress).
Comment 30 Olivier Fourdan 2018-02-21 17:34:08 UTC
I've filed two MR (gtk3 and gtk4) for this here:

gtk3: https://gitlab.gnome.org/GNOME/gtk/merge_requests/31
gtk4: https://gitlab.gnome.org/GNOME/gtk/merge_requests/32
Comment 31 Olivier Fourdan 2018-03-27 08:37:28 UTC
Both branches have now been merged in gitlab (thanks Matthias!), closing.