The xcb_connection_t instance that is used here comes from
XGetXCBConnection(), is created by XOpenDisplay(), and is owned by the
returned Display*. Calling xcb_disconnect() directly on it leads to
various use-after-frees during shutdown, as reported by valgrind. The
first one of the about 30 errors is:
Invalid read of size 4
at 0x71F2051: xcb_take_socket (in /usr/lib64/libxcb.so.1.1.0)
by 0x78551DD: ??? (in /usr/lib64/libX11.so.6.3.0)
by 0x7855A14: _XFlush (in /usr/lib64/libX11.so.6.3.0)
by 0x7858504: _XGetRequest (in /usr/lib64/libX11.so.6.3.0)
by 0x7838966: XFreeGC (in /usr/lib64/libX11.so.6.3.0)
by 0x783238B: XCloseDisplay (in /usr/lib64/libX11.so.6.3.0)
by 0x4E680C2: wlr_x11_backend_destroy (backend.c:333)
by 0x4E57E94: wlr_backend_destroy (backend.c:39)
by 0x4E629FB: multi_backend_destroy (backend.c:47)
by 0x4E62B5A: handle_display_destroy (backend.c:90)
by 0x50B7E9F: ??? (in /usr/lib64/libwayland-server.so.0.1.0)
by 0x50B8476: wl_display_destroy (in /usr/lib64/libwayland-server.so.0.1.0)
Address 0xc14dda0 is 0 bytes inside a block of size 21,152 free'd
at 0x4C2DD18: free (vg_replace_malloc.c:530)
by 0x4E680A5: wlr_x11_backend_destroy (backend.c:330)
by 0x4E57E94: wlr_backend_destroy (backend.c:39)
by 0x4E629FB: multi_backend_destroy (backend.c:47)
by 0x4E62B5A: handle_display_destroy (backend.c:90)
by 0x50B7E9F: ??? (in /usr/lib64/libwayland-server.so.0.1.0)
by 0x50B8476: wl_display_destroy (in /usr/lib64/libwayland-server.so.0.1.0)
by 0x40C54E: main (main.c:84)
Block was alloc'd at
at 0x4C2EA1E: calloc (vg_replace_malloc.c:711)
by 0x71F0C60: xcb_connect_to_fd (in /usr/lib64/libxcb.so.1.1.0)
by 0x71F4BD4: xcb_connect_to_display_with_auth_info (in /usr/lib64/libxcb.so.1.1.0)
by 0x7854AA1: _XConnectXCB (in /usr/lib64/libX11.so.6.3.0)
by 0x7845481: XOpenDisplay (in /usr/lib64/libX11.so.6.3.0)
by 0x4E681B6: wlr_x11_backend_create (backend.c:376)
by 0x4E580EE: wlr_backend_autocreate (backend.c:99)
by 0x40C27D: main (main.c:35)
Normally, one would expect this to crash during XCloseDisplay() when
xcb_disconnect() is called again and frees the same data again (glibc would
detect a double free). However, XCloseDisplay() tries to clean up some internal
caches first for which it has to send requests to the X11 server (e.g. the
XFreeGC() above). This fails since the file descriptor was already closed,
which causes an IO error. Xlib's _XDefaultIOError() handles this by printing an
error message and calling exit(1).
Thus, the only symptom of this problem was compositors exiting
mid-shutdown and printing an error message:
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 6 requests (6 known processed) with 0 events remaining.
Fixes: https://github.com/swaywm/wlroots/issues/745
Signed-off-by: Uli Schlachter <psychon@znc.in>
==12021==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000015698 at pc 0x7f1a9abe1c09 bp 0x7ffe9068f6b0 sp 0x7ffe9068f6a0
WRITE of size 4 at 0x617000015698 thread T0
#0 0x7f1a9abe1c08 in pointer_handle_leave ../backend/wayland/wl_seat.c:40
#1 0x7f1a96ae7d1d in ffi_call_unix64 (/lib64/libffi.so.6+0x5d1d)
#2 0x7f1a96ae768e in ffi_call (/lib64/libffi.so.6+0x568e)
#3 0x7f1a988e0d8a (/lib64/libwayland-client.so.0+0x8d8a)
#4 0x7f1a988dd927 (/lib64/libwayland-client.so.0+0x5927)
#5 0x7f1a988debe3 in wl_display_dispatch_queue_pending (/lib64/libwayland-client.so.0+0x6be3)
#6 0x7f1a9abdd6d6 in dispatch_events ../backend/wayland/backend.c:28
#7 0x7f1a9a968c11 in wl_event_loop_dispatch (/lib64/libwayland-server.so.0+0x9c11)
#8 0x7f1a9a967449 in wl_display_run (/lib64/libwayland-server.so.0+0x8449)
#9 0x418dff in main ../rootston/main.c:81
#10 0x7f1a99b5ef29 in __libc_start_main (/lib64/libc.so.6+0x20f29)
#11 0x4057c9 in _start (/home/shared/wayland/wlroots/build/rootston/rootston+0x4057c9)
0x617000015698 is located 664 bytes inside of 696-byte region [0x617000015400,0x6170000156b8)
freed by thread T0 here:
#0 0x7f1a9af754b8 in __interceptor_free (/lib64/libasan.so.4+0xde4b8)
#1 0x7f1a9abe01ee in wlr_wl_output_destroy ../backend/wayland/output.c:194
#2 0x7f1a9ac12918 in wlr_output_destroy ../types/wlr_output.c:299
#3 0x7f1a9abe061b in xdg_toplevel_handle_close ../backend/wayland/output.c:255
#4 0x7f1a96ae7d1d in ffi_call_unix64 (/lib64/libffi.so.6+0x5d1d)
#5 0x7f1a96ae768e in ffi_call (/lib64/libffi.so.6+0x568e)
#6 0x7f1a988e0d8a (/lib64/libwayland-client.so.0+0x8d8a)
#7 0x7f1a988dd927 (/lib64/libwayland-client.so.0+0x5927)
#8 0x7f1a988debe3 in wl_display_dispatch_queue_pending (/lib64/libwayland-client.so.0+0x6be3)
#9 0x7f1a9abdd6d6 in dispatch_events ../backend/wayland/backend.c:28
#10 0x7f1a9a968c11 in wl_event_loop_dispatch (/lib64/libwayland-server.so.0+0x9c11)
#11 0x7f1a9a967449 in wl_display_run (/lib64/libwayland-server.so.0+0x8449)
#12 0x418dff in main ../rootston/main.c:81
#13 0x7f1a99b5ef29 in __libc_start_main (/lib64/libc.so.6+0x20f29)
#14 0x4057c9 in _start (/home/shared/wayland/wlroots/build/rootston/rootston+0x4057c9)
previously allocated by thread T0 here:
#0 0x7f1a9af75a38 in __interceptor_calloc (/lib64/libasan.so.4+0xdea38)
#1 0x7f1a9abe0703 in wlr_wl_output_create ../backend/wayland/output.c:272
#2 0x7f1a9abdd8eb in wlr_wl_backend_start ../backend/wayland/backend.c:55
#3 0x7f1a9abbeb49 in wlr_backend_start ../backend/backend.c:28
#4 0x7f1a9abd8ce1 in multi_backend_start ../backend/multi/backend.c:24
#5 0x7f1a9abbeb49 in wlr_backend_start ../backend/backend.c:28
#6 0x418c32 in main ../rootston/main.c:58
#7 0x7f1a99b5ef29 in __libc_start_main (/lib64/libc.so.6+0x20f29)
#8 0x4057c9 in _start (/home/shared/wayland/wlroots/build/rootston/rootston+0x4057c9)
Some clients create an xdg_surface, then create an xdg_toplevel,
but don't map it and destroy it right after. The xdg_surface ends
up in a state where it isn't mapped but role-specific resources
have been allocated. xdg_surface_unmap needs to free these
resources without emitting the unmap signal.
By using the same vertex shader and adding alpha to the fragment shader
for external textures we can:
- use alpha blending
- have wlr_gles2_render_texture_with_matrix work with
the GL_TEXTURE_EXTERNAL_OES. So far this failed
since we passed in alpha which was unknown by fragment_src_external
Allow to set the texture target type when generating/binding the
texture. This allows us to attach the texture type to the texture so we
don't have to keep the logic elsewhere.