-
Notifications
You must be signed in to change notification settings - Fork 110
Description
Dear maintainer,
tldr; An uncaught exception in parse_error_response()
causes the next call to get_input_focus()
to hang indefinitely with 100% CPU usage.
Details
OS: Debian Bookworm
Python version: 3.10.9
python3-xlib version: 0.33-1
The application I use calls win.get_full_property(self._NET_WM_NAME, 0)
where win
is instance of Window
from drawable.py
and self._NET_WM_NAME
is 326.
The traceback is as follows:
Traceback (most recent call last):
File "/usr/bin/keyd-application-mapper", line 156, in get_title
x = win.get_full_property(self._NET_WM_NAME, 0).value
File "/usr/lib/python3/dist-packages/Xlib/xobject/drawable.py", line 476, in get_full_property
prop = self.get_property(property, property_type, sizehint,
File "/usr/lib/python3/dist-packages/Xlib/xobject/drawable.py", line 455, in get_property
r = request.GetProperty(display = self.display,
File "/usr/lib/python3/dist-packages/Xlib/protocol/rq.py", line 1368, in __init__
self.reply()
File "/usr/lib/python3/dist-packages/Xlib/protocol/rq.py", line 1380, in reply
self._display.send_and_recv(request = self._serial)
File "/usr/lib/python3/dist-packages/Xlib/protocol/display.py", line 612, in send_and_recv
gotreq = self.parse_response(request)
File "/usr/lib/python3/dist-packages/Xlib/protocol/display.py", line 719, in parse_response
gotreq = self.parse_error_response(request) or gotreq
File "/usr/lib/python3/dist-packages/Xlib/protocol/display.py", line 745, in parse_error_response
req = self.get_waiting_request(e.sequence_number)
AttributeError: 'BadRRModeError' object has no attribute 'sequence_number'
The BadRRModeError
exception was added by disp.extension_add_error(BadRRMode, BadRRModeError)
in Xlib/ext/randr.py
and seems to be quite different from the other errors defined in Xlib/error.py
and in particular the 'sequence_number' attribute does not exist.
The application I use logs this error and proceeds by calling dpy.next_event()
and then dpy.dpy.get_input_focus()
where dpy = Xlib.display.Display()
.
The last call hangs indefinitely with 100% CPU usage and seems to do so because of the previous BadRRModeError
.
I used Python's faulthandler module to investigate where the code hangs (i.e. python3 -X faulthandler application.py
and then sending SIGARBT
to see where the main thread is). I did this several times and every time the thread was busy inside the send_and_recv()
function in Xlib/protocol/display.py
:
Current thread 0x00007f30fc5fe040 (most recent call first):
File "/usr/lib/python3/dist-packages/Xlib/protocol/display.py", line 515 in send_and_recv
File "/usr/lib/python3/dist-packages/Xlib/protocol/rq.py", line 1380 in reply
File "/usr/lib/python3/dist-packages/Xlib/protocol/rq.py", line 1368 in __init__
File "/usr/lib/python3/dist-packages/Xlib/display.py", line 607 in get_input_focus
File "/usr/bin/keyd-application-mapper", line 200 in run
File "/usr/bin/keyd-application-mapper", line 419 in <module>
Workaround
I'm not very familiar with python-xlib internals, so I still don't fully understand what is going on.
A temporary solution for my case is to simply remove the line disp.extension_add_error(BadRRMode, BadRRModeError)
which instead causes the error to appear as:
Traceback (most recent call last):
File "/usr/bin/keyd-application-mapper", line 174, in get_window_info
return (cls[1], get_title(win))
File "/usr/bin/keyd-application-mapper", line 155, in get_title
raise err from None
File "/usr/bin/keyd-application-mapper", line 153, in get_title
title = win.get_full_property(self._NET_WM_NAME, 0).value.decode('utf8')
File "/usr/lib/python3/dist-packages/Xlib/xobject/drawable.py", line 476, in get_full_property
prop = self.get_property(property, property_type, sizehint,
File "/usr/lib/python3/dist-packages/Xlib/xobject/drawable.py", line 455, in get_property
r = request.GetProperty(display = self.display,
File "/usr/lib/python3/dist-packages/Xlib/protocol/rq.py", line 1368, in __init__
self.reply()
File "/usr/lib/python3/dist-packages/Xlib/protocol/rq.py", line 1388, in reply
raise self._error
Xlib.error.BadValue: <class 'Xlib.error.BadValue'>: code = 2, resource_id = 10, sequence_number = 4818, major_opcode = 20, minor_opcode = 0
which does not cause get_input_focus()
to hang.