frispete/PyQxtGlobalShortcut

SIGSEGV crashes on Qt application exit in QxtX11Data::QxtX11Data()

Closed this issue · 0 comments

Leaving this note here to anyone, who is stumbling across this issue in future.

You experience SIGSEGV crashes in QxtX11Data::QxtX11Data(), when your application exits.
Here's why:

PyQt tries to tear down everything on exit, which is a good thing.

Unfortunately, with newer Qt5 (I've observed this with 5.12.3 on openSUSE Tumbleweed), the behavior changed, such that

        void *display = native->nativeResourceForScreen(QByteArray("display"),
                                                        QGuiApplication::primaryScreen());

returns a NULLPTR during shutdown, resulting in crashes from the next statement:

        m_display = reinterpret_cast<Display *>(display);

We could catch this of course, but I refrained from committing such a patch, because now, this results in:

QxtGlobalShortcut failed to unregister: "Meta+W"
QxtGlobalShortcut failed to unregister: "Meta+A"

In order to fix this issue, I recommend triggering the destructor explicitly in your exit code, before QApplication is taken down, e.g.:

        # call QxtGlobalShortcut destructors explicitly here to avoid SIGSEGV crashes in
        # QxtX11Data::QxtX11Data() called from QxtGlobalShortcutPrivate::unsetShortcut()
        self.dialShortcut = None
        self.quickDialShortcut = None
        QApplication.instance().quit()

A further note: of course, we could disable the tear down feature in sip:

import sip
sip.setdestroyonexit(False)

but again, I wouldn't recommend this, because the global shortcuts wouldn't unregistered, which may result in trouble down the road. Better identify such issues, and deal with it.

I hope, this is helpful for somebody...