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 <shawn.rutledge@digia.com>
This commit is contained in:
Jan Kundrát 2015-03-12 14:10:06 +01:00 committed by Shawn Rutledge
parent 044160556c
commit a1b84fe729

View File

@ -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<QXcbScreen *>(screen)->xcb_connection();
xcb_bell(connection, 0);
}
static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s)
{
if (!s)
return Q_NULLPTR;
return static_cast<const QXcbScreen *>(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<void *>(quintptr(screen->connection()->time()));
}
void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen)
{
if (!screen)
return Q_NULLPTR;
return reinterpret_cast<void *>(quintptr(screen->connection()->netWmUserTime()));
}
void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen)
{
if (!screen)
return Q_NULLPTR;
return reinterpret_cast<void *>(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<QXcbScreen *>(screen->handle())->connection()->setTime(time);
if (screen) {
static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time);
}
}
void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time)
{
static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time);
if (screen) {
static_cast<QXcbScreen *>(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<QXcbScreen *>(window->screen()->handle());
QScreen *qs = window->screen();
screen = static_cast<QXcbScreen *>(qs ? qs->handle() : Q_NULLPTR);
} else {
screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle());
QScreen *qs = QGuiApplication::primaryScreen();
screen = static_cast<QXcbScreen *>(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)