From a1b84fe729d7ccf4c1469d35d0793b45034d5fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= Date: Thu, 12 Mar 2015 14:10:06 +0100 Subject: Fix bunch of other segfaults due to null screens This was motivated by a real segfault: #0 QScreen::handle (this=0x0) at qtgui-5.5.9999/work/qtgui-5.5.9999/src/gui/kernel/qscreen.cpp:112 #1 0x00007faaf5d5e85e in QXcbNativeInterface::connectionForWindow (this=this@entry=0x7fab04d684f0, window=window@entry=0x0) at qtgui-5.5.9999/src/plugins/platforms/xcb/qxcbnativeinterface.cpp:483 #2 0x00007faaf5d5fa53 in QXcbNativeInterface::nativeResourceForWindow (this=this@entry=0x7fab04d684f0, resourceString=..., window=window@entry=0x0) at qtgui-5.5.9999/work/qtgui-5.5.9999/src/plugins/platforms/xcb/qxcbnativeinterface.cpp:304 #3 0x00007fab048b8b57 in QX11Info::connection () at /var/tmp/portage/dev-qt/qtx11extras-5.5.9999/work/qtx11extras-5.5.9999/src/x11extras/qx11info_x11.cpp:358 #4 0x00007fab02ce14c6 in NETEventFilter::nativeEventFilter (this=0x7fab04ea5e70, ev=0x7faaec003a60) at kwindowsystem-5.7.0/work/kwindowsystem-5.7.0/src/kwindowsystem_x11.cpp:229 ...at which point I tried to stop playing the get-backtrace-patch-rebuild-repeat cycle and looked at the stuff which looked fishy to my untrained eye. So this is speculative in nature, but I think that each of these cases can be hit and dereference a nullptr. Change-Id: I046debaa1b49fa55e876247fc62f3eb924496fe8 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 47 +++++++++++++++++------ 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 0688898cae..3a4539c5e6 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -92,13 +92,21 @@ QXcbNativeInterface::QXcbNativeInterface() : void QXcbNativeInterface::beep() // For QApplication::beep() { - QPlatformScreen *screen = QGuiApplication::primaryScreen()->handle(); + QScreen *priScreen = QGuiApplication::primaryScreen(); + if (!priScreen) + return; + QPlatformScreen *screen = priScreen->handle(); + if (!screen) + return; xcb_connection_t *connection = static_cast(screen)->xcb_connection(); xcb_bell(connection, 0); } static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s) { + if (!s) + return Q_NULLPTR; + return static_cast(s->handle())->connection()->systemTrayTracker(); } @@ -386,16 +394,25 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio void *QXcbNativeInterface::appTime(const QXcbScreen *screen) { + if (!screen) + return Q_NULLPTR; + return reinterpret_cast(quintptr(screen->connection()->time())); } void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen) { + if (!screen) + return Q_NULLPTR; + return reinterpret_cast(quintptr(screen->connection()->netWmUserTime())); } void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen) { + if (!screen) + return Q_NULLPTR; + return reinterpret_cast(quintptr(screen->connection()->getTimestamp())); } @@ -431,20 +448,24 @@ void *QXcbNativeInterface::display() #ifdef XCB_USE_XLIB QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); - return defaultConnection->xlib_display(); -#else - return 0; + if (defaultConnection) + return defaultConnection->xlib_display(); #endif + return Q_NULLPTR; } void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time) { - static_cast(screen->handle())->connection()->setTime(time); + if (screen) { + static_cast(screen->handle())->connection()->setTime(time); + } } void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) { - static_cast(screen->handle())->connection()->setNetWmUserTime(time); + if (screen) { + static_cast(screen->handle())->connection()->setNetWmUserTime(time); + } } void QXcbNativeInterface::setStartupId(const char *data) @@ -460,9 +481,11 @@ QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window) { QXcbScreen *screen; if (window) { - screen = static_cast(window->screen()->handle()); + QScreen *qs = window->screen(); + screen = static_cast(qs ? qs->handle() : Q_NULLPTR); } else { - screen = static_cast(QGuiApplication::primaryScreen()->handle()); + QScreen *qs = QGuiApplication::primaryScreen(); + screen = static_cast(qs ? qs->handle() : Q_NULLPTR); } return screen; } @@ -471,23 +494,23 @@ void *QXcbNativeInterface::displayForWindow(QWindow *window) { #if defined(XCB_USE_XLIB) QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen->connection()->xlib_display(); + return screen ? screen->connection()->xlib_display() : Q_NULLPTR; #else Q_UNUSED(window); - return 0; + return Q_NULLPTR; #endif } void *QXcbNativeInterface::connectionForWindow(QWindow *window) { QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen->xcb_connection(); + return screen ? screen->xcb_connection() : Q_NULLPTR; } void *QXcbNativeInterface::screenForWindow(QWindow *window) { QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen->screen(); + return screen ? screen->screen() : Q_NULLPTR; } void QXcbNativeInterface::addHandler(QXcbNativeInterfaceHandler *handler) -- cgit v1.2.3