From d1670f679d8ce7c47bca7fca9328d26283372730 Mon Sep 17 00:00:00 2001 From: Nils <> Date: Fri, 26 Jun 2020 20:56:50 +0200 Subject: [PATCH] Install faulthandler for QT bugs, set thread name to program name --- template/start.py | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/template/start.py b/template/start.py index 809e866..b88cffd 100644 --- a/template/start.py +++ b/template/start.py @@ -27,6 +27,12 @@ We don't want to use all the libraries, including the big Qt one, only to end up Same with the tests if jack or nsm are running. """ +#Give at least some feedback when C libs crash. +#Will still not work for the common case that PyQt crashes and ends Python. +#But every bit helps when hunting bugs. +import faulthandler; faulthandler.enable() + + from engine.config import * #includes METADATA only. No other environmental setup is executed. from template.qtgui.chooseSessionDirectory import ChooseSessionDirectory from template.qtgui.helper import setPaletteAndFont #our error boxes shall look like the rest of the program @@ -67,6 +73,8 @@ Nuitka complies that in, when make is finished we delete it. import sys import os import os.path +from PyQt5.QtWidgets import QApplication +from PyQt5 import QtGui logger.info(f"Python Version {sys.version}") @@ -135,7 +143,9 @@ else: logger.info("PATHS: {}".format(PATHS)) -from PyQt5.QtWidgets import QApplication +#Construct QAppliction before constantsAndCOnfigs, which has the fontDB +QtGui.QGuiApplication.setDesktopSettingsAware(False) #We need our own font so the user interface stays predictable +QtGui.QGuiApplication.setDesktopFileName(PATHS["desktopfile"]) qtApp = QApplication(sys.argv) setPaletteAndFont(qtApp) @@ -154,7 +164,7 @@ def setProcessName(executableName): """From https://stackoverflow.com/questions/31132342/change-process-name-while-executing-a-python-script """ - import ctypes + import ctypes, ctypes.util lib = ctypes.cdll.LoadLibrary(None) prctl = lib.prctl prctl.restype = ctypes.c_int @@ -166,6 +176,27 @@ def setProcessName(executableName): raise OSError("prctl result: %d" % result) set_proctitle(executableName.encode()) + + libpthread_path = ctypes.util.find_library("pthread") + if not libpthread_path: + return + + libpthread = ctypes.CDLL(libpthread_path) + if hasattr(libpthread, "pthread_setname_np"): + _pthread_setname_np = libpthread.pthread_setname_np + + _pthread_self = libpthread.pthread_self + _pthread_self.argtypes = [] + _pthread_self.restype = ctypes.c_void_p + + _pthread_setname_np.argtypes = [ctypes.c_void_p, ctypes.c_char_p] + _pthread_setname_np.restype = ctypes.c_int + + if _pthread_setname_np is None: + return + + _pthread_setname_np(_pthread_self(), executableName.encode()) + def checkNsmOrExit(prettyName): """Check for NSM""" #NSM changes our cwd to whereever we started new-session-manager from. @@ -275,7 +306,11 @@ if args.directory: checkNsmOrExit(METADATA["name"]) checkJackOrExit(args.mute, METADATA["name"]) -setProcessName(METADATA["shortName"]) +try: + #Only cosmetics + setProcessName(METADATA["shortName"]) +except: + pass if args.mute: """This uses the fact that imports are global and only triggered once.