Indefinite SelectionRead() requests cannot be cancelled/aborted
Currently, if a remote desktop client doesn't provide the clipboard content (in time), mutter will abort the SelectionTransfer()
. This works fine.
But if an application on the server side, doesn't provide the clipboard content (at all), mutter doesn't abort that request too.
Instead, gnome-remote-desktop waits indefinitely for content on the pipe. Since this action happens on the main thread in g-r-d, stopping the remote desktop session won't work.
The only way to get rid of this situation is by killing g-r-d.
To reproduce the situation:
- Connect with a RDP client to g-r-d (since the RDP backend can handle images via the clipboard)
- Run libreoffice (writer) on the server side
- Insert in libreoffice (writer) some graph.
- Copy that graph
- Try to paste it on the client side
g-r-d will now try to fetch the image content via SelectionRead()
, but libreoffice (writer) won't (bug in lo) provide that image.
The effect is that g-r-d will indefinitely hang in len = read (fd, buffer, G_N_ELEMENTS (buffer));
(in g-r-d (grd-session.c
)).
To get rid of this situation, the read()
call needs to be stopped somehow. mutter could maybe run some timeout source to close the fd at some point. Not sure though how situations should then be handled where the application already provided some data (len is then > 0).
I also don't know whether libreoffice already wrote some data, since len
is in my backtrackes always optimized out.
At the same time, I am thinking what g-r-d could do. Having another thread that runs a GSource to cancel such requests upon timeout or disconnection doesn't sound nice, but if the remote desktop client disconnects, g-r-d should also be able to stop the SelectionRead()
request.
Affects obviously mutter-40 and g-r-d-40, since we implemented clipboard support for GNOME 40.
CC: @jadahl
g-r-d backtrace
Thread 1 (LWP 2032 "gnome-remote-de"):
#0 0x00007fe3128fa87c in read () at /usr/lib/libpthread.so.0
#1 0x000055ee29ac2ecc in read (__nbytes=1024, __buf=0x7ffff3d39480, __fd=77) at /usr/include/bits/unistd.h:47
len = <optimized out>
buffer = "\000\000\000\000\000\000\000\000\000\265\212Y\"\355\216\027P\225\323\363\377\177\000\000K\367\376\022\343\177\000\000q`\376\022\343\177\000\000\260n\002,\356U\000\000P\225\323\363\377\177\000\000\001\000\000\000\000\000\000\000:\367\376\022\343\177\000\000\331\363\375\022\343\177\000\000P\225\323\363\377\177\000\000\212&\n\302\317", '\000' <repeats 11 times>, "\030\225\323\363\377\177\000\000\340\226\323\363\377\177\000\000\004\000\000\000\000\000\000\000p\224\000\374\342\177\000\000\000\265\212Y\"\355\216\027\320\346\065,\356U\000\000 \000\000\334\342\177\000\000p\032\000\334\342\177\000\000X\000\000\000\000\000\000\000X\000\000\000\000\000\000\000`\032\000\334\342\177\000\000p\000\000\000\000\000\000\000"...
priv = <optimized out>
error = 0x0
fd_variant = 0x55ee2b9516c0
fd_list = 0x55ee2c04ccb0
fd_idx = 0
fd = 77
mime_type_string = <optimized out>
data = 0x55ee2b9a5760
#2 grd_session_selection_read (session=<optimized out>, mime_type=mime_type@entry=GRD_MIME_TYPE_IMAGE_PNG, size=size@entry=0x7ffff3d398fc) at ../gnome-remote-desktop/src/grd-session.c:364
len = <optimized out>
buffer = "\000\000\000\000\000\000\000\000\000\265\212Y\"\355\216\027P\225\323\363\377\177\000\000K\367\376\022\343\177\000\000q`\376\022\343\177\000\000\260n\002,\356U\000\000P\225\323\363\377\177\000\000\001\000\000\000\000\000\000\000:\367\376\022\343\177\000\000\331\363\375\022\343\177\000\000P\225\323\363\377\177\000\000\212&\n\302\317", '\000' <repeats 11 times>, "\030\225\323\363\377\177\000\000\340\226\323\363\377\177\000\000\004\000\000\000\000\000\000\000p\224\000\374\342\177\000\000\000\265\212Y\"\355\216\027\320\346\065,\356U\000\000 \000\000\334\342\177\000\000p\032\000\334\342\177\000\000X\000\000\000\000\000\000\000X\000\000\000\000\000\000\000`\032\000\334\342\177\000\000p\000\000\000\000\000\000\000"...
priv = <optimized out>
error = 0x0
fd_variant = 0x55ee2b9516c0
fd_list = 0x55ee2c04ccb0
fd_idx = 0
fd = 77
mime_type_string = <optimized out>
data = 0x55ee2b9a5760
#3 0x000055ee29ac785f in grd_clipboard_request_server_content_for_mime_type (clipboard=clipboard@entry=0x55ee2b91eb80, mime_type=mime_type@entry=GRD_MIME_TYPE_IMAGE_PNG, size=size@entry=0x7ffff3d398fc) at ../gnome-remote-desktop/src/grd-clipboard.c:92
priv = 0x55ee2b91eb60
data = <optimized out>
#4 0x000055ee29ac79f0 in request_server_format_data (user_data=0x7fe2dc001a40, user_data@entry=<error reading variable: value has been optimized out>) at ../gnome-remote-desktop/src/grd-clipboard-rdp.c:1074
request_context = 0x7fe2dc001a40
clipboard_rdp = 0x55ee2b91eb80
clipboard = 0x55ee2b91eb80
cliprdr_context = 0x55ee2c316d90
format_data_response = {msgType = 0, msgFlags = 0, dataLen = 0, requestedFormatData = 0x0}
mime_type = GRD_MIME_TYPE_IMAGE_PNG
src_format_id = 0
dst_format_id = 53265
src_data = 0x0
dst_data = 0x0
src_size = 0
dst_size = 0
success = <optimized out>
#5 0x00007fe312f92f44 in g_timeout_dispatch (source=0x7fe2dc001ae0, callback=<optimized out>, user_data=<optimized out>) at ../glib/glib/gmain.c:4877
timeout_source = 0x7fe2dc001ae0
again = <optimized out>
#6 0x00007fe312f9273b in g_main_dispatch (context=0x55ee2b920a20) at ../glib/glib/gmain.c:3325
dispatch = 0x7fe312f92f30 <g_timeout_dispatch>
prev_source = 0x0
begin_time_nsec = 892314305504
was_in_call = <optimized out>
user_data = 0x7fe2dc001a40
callback = 0x55ee29ac78b8 <request_server_format_data>
cb_funcs = 0x7fe3130703a0 <g_source_callback_funcs>
cb_data = 0x7fe2dc001960
need_destroy = <optimized out>
source = 0x7fe2dc001ae0
current = 0x55ee2b90fa00
i = 0
#7 g_main_context_dispatch (context=0x55ee2b920a20) at ../glib/glib/gmain.c:4043
#8 0x00007fe312fe53b1 in g_main_context_iterate.constprop.0 (context=context@entry=0x55ee2b920a20, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4119
max_priority = 2147483647
timeout = -1
some_ready = 1
nfds = 4
allocated_nfds = 4
fds = 0x7fe30000ba30
begin_time_nsec = 892313981028
#9 0x00007fe312f910d9 in g_main_context_iteration (context=context@entry=0x55ee2b920a20, may_block=may_block@entry=1) at ../glib/glib/gmain.c:4184
retval = <optimized out>
#10 0x00007fe312e533c6 in g_application_run (application=application@entry=0x55ee2b91e950, argc=-204236060, argv=<optimized out>) at ../glib/gio/gapplication.c:2559
arguments = 0x55ee2b9529d0
status = 0
context = 0x55ee2b920a20
acquired_context = <optimized out>
__func__ = "g_application_run"
#11 0x000055ee29abf243 in main (argc=<optimized out>, argv=<optimized out>) at ../gnome-remote-desktop/src/grd-daemon.c:381
settings = <optimized out>
print_version = 0
rdp_port = -1
vnc_port = -1
entries = {{long_name = 0x55ee29add7a2 "version", short_name = 0 '\000', flags = 0, arg = G_OPTION_ARG_NONE, arg_data = 0x7ffff3d39b64, description = 0x55ee29add79c "Print version", arg_description = 0x0}, {long_name = 0x55ee29add7aa "rdp-port", short_name = 0 '\000', flags = 0, arg = G_OPTION_ARG_INT, arg_data = 0x7ffff3d39b60, description = 0x55ee29add7b3 "RDP port", arg_description = 0x0}, {long_name = 0x55ee29add7bc "vnc-port", short_name = 0 '\000', flags = 0, arg = G_OPTION_ARG_INT, arg_data = 0x7ffff3d39b5c, description = 0x55ee29add7c5 "VNC port", arg_description = 0x0}, {long_name = 0x0, short_name = 0 '\000', flags = 0, arg = G_OPTION_ARG_NONE, arg_data = 0x0, description = 0x0, arg_description = 0x0}}
context = 0x55ee2b9182e0
app = 0x55ee2b91e950
error = 0x0
(gdb)