ponty / PyVirtualDisplay

Python wrapper for Xvfb, Xephyr and Xvnc
BSD 2-Clause "Simplified" License
709 stars 78 forks source link

python: Fatal IO error 0 (Success) on X server #31

Closed twmr closed 2 years ago

twmr commented 6 years ago

I get the above error message when the following pyqt script terminates

import sys

import pyvirtualdisplay
# Import the core and GUI elements of Qt
from PyQt4.QtCore import *
from PyQt4.QtGui import *

virtual_display = pyvirtualdisplay.Display(
    backend='xvfb', size=(800, 600),
    color_depth=16, use_xauth=False)
virtual_display.start()
if not virtual_display.is_alive():
    ret = virtual_display.return_code
    raise RuntimeError("Xvfb exited with exit code {0}".format(ret))

qt_app = QApplication(sys.argv)
label = QLabel('Hello, world!')
label.show()

# Run the application's event loop
# qt_app.exec_()
virtual_display.stop()

This error message causes the process to return a non-zero exit status

> echo $?
1

I tested this in a cpython3.6 conda environemnt with pyqt-4.11.4 and pyvirtualdisplay-0.2.1. To fix this we probably have to stop the xvfb virtual display after the pyqt part disconnected itself from xvfb, right? But how is this possible?

See also https://github.com/The-Compiler/pytest-xvfb/issues/11 and https://github.com/The-Compiler/pytest-xvfb/issues/1

twmr commented 6 years ago

I've just tested it in the same conda environment but with an updated pyqt (5.6.0), where I don't get this error. If you have any idea how to resolve the pyqt4 issue, that would be great.

ponty commented 4 years ago

It is not a pyvirtualdisplay bug because I get the same error message using only os.system. Here is the converted program and error message:

import sys, os, time

import pyvirtualdisplay

os.system("Xvfb :99 &")
time.sleep(1)
os.environ["DISPLAY"] = ":99"

# Import the core and GUI elements of Qt
from PyQt4.QtCore import *
from PyQt4.QtGui import *

qt_app = QApplication(sys.argv)
label = QLabel("Hello, world!")
label.show()

print("killall Xvfb")
os.system("killall Xvfb")
$ python3 crash.py 
killall Xvfb
python3: Fatal IO error 0 (Success) on X server :99.

I think that PyQt4 doesn't tolerate if the display is destroyed so the solution is to run it in a subprocess. e.g. xvfb-run python3 example.py