
I summarize my investigation results here to make it visible and hope, someone can find a solution for this later (beyond the proposed work-around)... Problem description: ------------------- BiT uses the "QApplication" Qt5 class for its GUI. In the context of the new feature "Diagnostics about Qt5 theme" https://github.com/bit-team/backintime/pull/1469/files#r1254526865 and my upcoming PR to fix all systemtray icon issues @buhtz and me could not find a reliable way to determine if a "QApplication" can be instantiated without causing a Python crash (SIGABRT with core dump) in some cases where Qt5 is unable to initalize itself (e.g. on a headless console-only system or if a non-supported Qt5-plugin is configured). Note: A core dump is snapshot of certain memory regions of the process at the time it crashed. It can be analyzed postmortem using debuggers like GDB. Symptoms: -------- Qt5 aborts Python with this output: > python3 qapp_test.py qt.qpa.xcb: could not connect to display qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, xcb. Aborted (core dumped) Minimal reproducible code example: --------------------------------- # File: qapp_test.py # try: from PyQt5.QtWidgets import QApplication, QSystemTrayIcon app = QApplication(['']) if QSystemTrayIcon.isSystemTrayAvailable(): print("systrayicon works") except: print(f"Exception {repr(e)}") Reason: ------- Qt5 uses the Macro "qFatal()" if a QApplication class instance cannot be created: https://doc.qt.io/qt-5/qtglobal.html#qFatal which sends a SIGABRT ("abort") signal on Linux: https://codebrowser.dev/qt5/qtbase/src/corelib/global/qlogging.h.html#168 https://www.qtcentre.org/threads/59684-qFatal-is-killing-my-application-with... TODO Find the exact Qt5 code for this. I could see the SIGABRT in the core dump... This SIGABRT signal is sent from the Python app process to the parent (Python3 Interpreter) and cannot (!) be handled in Python (e.g. via "signal.signal(signal.SIGABRT, signal.SIG_IGN") because Qt5 seems to exit the process immediately. https://docs.python.org/3/library/signal.html > A Python signal handler does not get executed inside the low-level (C) signal handler. > Instead, the low-level signal handler sets a flag which tells the virtual machine > to execute the corresponding Python signal handler at a later point Possible work-around: -------------------- Proposed by @buhtz: Spawn a sub process with above example code and check for the SIGABRT signal (or perhaps an expected return code or output). Impact: - Lower Performance (GUI startup time, diagnostics creation, systray icon creation) - The behaviour of Qt5 may not be the same as in the parent process (e.g. some missing explicit settings) -> to be investigated later