Schlagwort-Archive: QT5

Qt5: LoadLibrary-Fehler mit RDP unter Windows (ATI, OpenGL, Nextcloud)

Das Qt-Framework wird von vielen Projekten genutzt um grafische Oberflächen auf allen Betriebssystemen einheitlich entwickeln zu können. Bekannte Softwarepakete, welche Qt nutzen, sind unter Anderem: Nextcloud-Client, Owncloud-Client, FileZilla, Quassel, Mumble, MiniTube, Bitcoin-Qt, Scribus, LuminanceHDR, Audacious, Clementine, LMMS, VLC, AviDemux-qt, Shotcut, OpenShot, LibreCAD, FreeCAD, OpenSCAD, QOwnNotes, Calibre, KeePassX, KeePassXC, Wireshark und BlueStacks.

Eigentlich eine praktische Sache, jedoch mit einem Haken: Mit Qt5 versuchte man viele grafische Operationen per Hardwarebeschleunigung zu erledigen. Dies sorgt für schnellere Programme und weniger Systemlast. Für die Ansteuerung der Grafikkarte nutzt man hierbei OpenGL, welches auf allen gängigen Betriebssystemen verfügbar ist. Leider tritt man sich hierbei auch einige Probleme ein, so ist z.B. Windows dafür bekannt qualitativ zweifelhafte Treiber zu verteilen, welche stark auf Gaming optimiert sind, aber bei anderen Operationen gerne ins Straucheln kommen.

Ein recht verbreitetes Problem tritt dann auf, wenn eine AMD-Grafikkarte wie z.B. Radeon oder im System steckt, man jedoch auf den Windows-Rechner per Remote Desktop (RDP) zugreift. Windows lädt – auch wenn RDP genutzt wird – die Grafikkartentreiber. Ein Fehler in den ATI-Treibern, welcher bereits seit Ende der 2010er-Jahre bekannt ist, führt jedoch dazu, dass in RDP-Sitzungen Grafikoperationen nicht in Software ausgeführt oder von der Grafikkarte berechnet und zurückgegeben werden, sondern sie versuchen diese Trotzdem komplett in der GPU zu verarbeiten und brechen die Anfrage letztendlich ab. In vielen Anwendungen äußert sich das in fehlenden Grafikelementen oder Fehlermeldungen. So lässt sich z.B. der Nextcloud-Client gar nicht starten und Quittiert den Versuch die GUI per RDP zu öffnen mit einem fatalen Fehler. Es ist somit nicht möglich die Software per RDP zu starten.

Fehlermeldung NextCloud-Client: „LoadLibrary failed with error 87: The parameter is incorrect.“

Glücklicherweise kann man sich hierbei einer Eigenheit von „Shared Libraries“ zu nutze machen, welche peeter123 auf GitHub vorschlägt: Jede App bevorzugt seine eigene Version, nur wenn sie selbst nichts mitliefert wird auf jene des Systems zurückgegriffen. Im Falle des OpenGL-Bugs kann man also einfach statt der Microsoft/ATI-Version eine weniger kaputte nutzen. Hierzu eignet sich z.B. die Variante des Mesa-Projektes, welche die OpenGL-Operationen nicht direkt an die Grafikkarte sendet. Um diese nun einzubinden lädt man auf der Releases-Seite die letzte Release-Version für mingw herunter (mesa3d-xx.yy.zz-release-mingw.7z), öffnet diese (z.B. mit 7Zip) und kopiert aus dem Ordner x64 (für 64-Bit-Systeme) die Datei „opengl32.dll“ in den Ordner des betroffenen Programms, also z.B. C:\Program Files\Nextcloud. Hierdurch greift die Änderung nur für diese eine App und beeinflusst nicht alle installieren Programme. Fortan sollten die Operationen der Software ohne GPU-Treiber laufen und die Applikation somit auch per RDP lauffähig sein.

Durch diese Änderung verliert man zur potentiell etwas Geschwindigkeit in der betroffenen App, dies sollte bei aktuellen Systemen aber nicht groß auffallen – insbesondere, wenn man diese ohnehin nicht häufig aktiv nutzt. Immerhin ist die Software so auch remote nutzbar. Mit fortschreitender Migration auf Qt6 sollte sich das Problem mit der Zeit auch ganz von selbst erledigen: Dies nutzt statt OpenGL die jeweiligen Funktionen des Betriebssystems, welche auch auf Windows nicht ganz so kaputt sind.

[nvidia/qt5/kdenlive] Segfault on various KDE-software using NVIDIA 361.16

Uhm crap. The last system update just pulled a new beta version of NVIDIAs binary driver. Usually not that much of a deal, I went for testing due to a bug in their stable driver some years ago and never ran into a problem. Well, at least until now.  This time the testing-curse found its way into my system and I found myself no longer able to start my video editor kdenlive. Segmentation Fault. I suspected my setup first since I am running a rather unusual multihead configuration but could also with just one monitor I ran into the same problem. Well, looks like I have to dig deeper. Some gdb later at least a clue:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff0b640c5 in XScreenCount (dpy=0x0) at Macros.c:109
109	int XScreenCount(Display *dpy) { return (ScreenCount(dpy)); }
(gdb) bt
#0  0x00007ffff0b640c5 in XScreenCount (dpy=0x0) at Macros.c:109
#1  0x00007fffea7f50da in glXGetClientString () from /usr/lib/libGLX.so.0
#2  0x00007ffff7fed3b3 in ?? () from /usr/lib/qt/plugins/xcbglintegrations/libqxcb-glx-integration.so
#3  0x00007ffff7fed5b1 in ?? () from /usr/lib/qt/plugins/xcbglintegrations/libqxcb-glx-integration.so
#4  0x00007ffff686fc7b in QSGRenderLoop::instance() () from /usr/lib/libQt5Quick.so.5
#5  0x00007ffff68a19e5 in QQuickWindowPrivate::init(QQuickWindow*, QQuickRenderControl*) () from /usr/lib/libQt5Quick.so.5
#6  0x00007ffff694b68d in QQuickView::QQuickView(QWindow*) () from /usr/lib/libQt5Quick.so.5
#7  0x00000000006bd190 in ?? ()
#8  0x00000000006c3d7b in ?? ()
#9  0x00000000007af3cc in ?? ()
#10 0x000000000046346b in ?? ()
#11 0x00007ffff188e610 in __libc_start_main () from /usr/lib/libc.so.6
#12 0x0000000000463949 in _start ()

So XScreenCount or libGLX is the suspect. In my case GLX is provided by NVIDIAs binary driver (nouveau had limited multihead support last time I checked). Also some QT5-stuff is mentioned in the backtrace.

A bit of search engine voodoo later it turns out NVIDIA already acknowledged the problem. Aaron Plattner writes:

I reproduced the problem and tracked it down to this buggy code in Qt5’s qxcbglxintegration.cpp:

static bool vendorChecked = false;
    static bool glxPbufferUsable = true;
    if (!vendorChecked) {
        vendorChecked = true;
        const char *glxvendor = glXGetClientString(glXGetCurrentDisplay(), GLX_VENDOR);
        if (glxvendor && !strcmp(glxvendor, "ATI"))
            glxPbufferUsable = false;
    }

When this code is called during sddm-greeter startup, there’s no current GLX context, so this gets called with a NULL argument.

While here SDDM is not the problem I think kdenlive, which uses similar libraries, runs into the same problem. He also pushed a corresponding patch to NVIDIAs GIT-repository. Sadly the current HEAD is not 100% ABI compatible with the official driver release. Also I really didn’t want to get into my distributions xorg-packaging-foo. Ultimately I reverted to the current NVIDIA stable version 358.16 to get back into business. So – lesson confirmed: Beta releases can fix problems or cause problems. But who doesn’t like a bit of stability-gambling, right?