virtualbox-python
virtualbox-python copied to clipboard
Exception in event handler thread.
ENVIRONMENT
- Operating System: Windows 10 Pro (1903)
- Python version: 3.7.2:
- VirtualBox version: 6.1.4 r136177 (Qt5.6.2)
- VirtualBox SDK version: 1.0
- Location where VirtualBox SDK is installed: C:\Python3\python.exe (venv)
- virtualbox-python / pyvbox version: 2.0.0
- [x] Happens in latest
masterbranch?
SUMMARY
When registering a callback function using the: register_on_machine_state_changed() function an exception occurs in the event monitor thread.
STEPS TO REPRODUCE
The following example reproduces the problem:
import virtualbox
def callback(event):
print("Machine %s state changed to %s" % (event.machine_id, event.state))
vbox = virtualbox.VirtualBox()
vbox.register_on_machine_state_changed(callback) # Starts a thread which crashes in python 3.7 and VBox 6.1.4
session = virtualbox.Session()
machine = vbox.find_machine('<a machine>')
progress = machine.launch_vm_process(session, "gui", ''.encode()) # Workaround: use ''.encode() instead of just ''.
progress.wait_for_completion()
while True:
pass
EXPECTED RESULTS
To see the state changes of the machine as it starts.
ACTUAL RESULTS
Unhanded exception in callback:
Traceback (most recent call last):
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\events.py", line 56, in _event_monitor
callback(event_interface(event))
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library_base.py", line 130, in __init__
self._i = manager.cast_object(interface, self.__class__)._i
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\__init__.py", line 197, in cast_object
i = self.manager.queryInterface(interface_object._i, name)
File ".\test-virtualbox\venv-3\lib\site-packages\vboxapi\__init__.py", line 1082, in queryInterface
return self.platform.queryInterface(oIUnknown, sClassName)
File ".\test-virtualbox\venv-3\lib\site-packages\vboxapi\__init__.py", line 679, in queryInterface
return CastTo(oIUnknown, sClassName)
File ".\test-virtualbox\venv-3\lib\site-packages\win32com\client\__init__.py", line 141, in CastTo
ob = gencache.EnsureDispatch(ob)
File ".\test-virtualbox\venv-3\lib\site-packages\win32com\client\gencache.py", line 527, in EnsureDispatch
disp = win32com.client.Dispatch(prog_id)
File ".\test-virtualbox\venv-3\lib\site-packages\win32com\client\__init__.py", line 96, in Dispatch
return __WrapDispatch(dispatch, userName, resultCLSID, typeinfo, clsctx=clsctx)
File ".\test-virtualbox\venv-3\lib\site-packages\win32com\client\__init__.py", line 43, in __WrapDispatch
return dynamic.Dispatch(dispatch, userName, WrapperClass, typeinfo, clsctx=clsctx)
File ".\test-virtualbox\venv-3\lib\site-packages\win32com\client\dynamic.py", line 133, in Dispatch
typeinfo = IDispatch.GetTypeInfo()
AttributeError: 'NoneType' object has no attribute 'GetTypeInfo'
Traceback (most recent call last):
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library_base.py", line 201, in _call_method
ret = method(*in_params)
File ".\AppData\Local\Temp\gen_py\3.7\D7569351-1750-46F0-936E-BD127D5BC264x0x1x3.py", line 3398, in EventProcessed
, aEvent)
pywintypes.com_error: (-2147417851, 'The server threw an exception.', None, None)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".\Python3\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\events.py", line 60, in _event_monitor
event_source.event_processed(listener, event)
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library.py", line 30697, in event_processed
in_p=[listener, event])
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library_base.py", line 192, in _call
return self._call_method(method, in_p=in_p)
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library_base.py", line 214, in _call_method
errobj.msg = exc.args[2][2]
TypeError: 'NoneType' object is not subscriptable
Exception in thread Thread-6:
Traceback (most recent call last):
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library_base.py", line 201, in _call_method
ret = method(*in_params)
File ".\AppData\Local\Temp\gen_py\3.7\D7569351-1750-46F0-936E-BD127D5BC264x0x1x3.py", line 3398, in EventProcessed
, aEvent)
pywintypes.com_error: (-2147417851, 'The server threw an exception.', None, None)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".\Python3\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File ".\Python3\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\events.py", line 60, in _event_monitor
event_source.event_processed(listener, event)
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library.py", line 30697, in event_processed
in_p=[listener, event])
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library_base.py", line 192, in _call
return self._call_method(method, in_p=in_p)
File ".\test-virtualbox\venv-3\lib\site-packages\virtualbox\library_base.py", line 214, in _call_method
errobj.msg = exc.args[2][2]
TypeError: 'NoneType' object is not subscriptable
ANALYSIS
The event monitor thread contains the following code:
def _event_monitor(callback, event_source, listener, event_interface, quit):
global _callbacks
try:
while not quit.is_set():
try:
event = event_source.get_event(listener, 1000)
except library.VBoxError:
print("Unregistering %s due to VBoxError on get_event" %
listener, file=sys.stderr)
break
if event: <====
...
...
The Truth value testing for 'event' is implemented in the base class of the IEvent class (Interface). The code is:
def __nonzero__(self):
return bool(self._i)
However, in python 3 the function __bool__() has to be implemented for Truth testing.
PROPOSED SOLUTION
Add the following assignment after the above function in: .\Lib\site-packages\virtualbox\library_base.py
__bool__ = __nonzero__