XCB: Don't core-dump if we can't connect to the X displayName

Exit with error, but don't crash.

Change-Id: Ie05c6480d8a44fda817ffffd14d9dfd8c951beef
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
Thiago Macieira 2017-08-11 12:01:12 -07:00
parent baf1158c48
commit cdc79f5ebc
3 changed files with 30 additions and 8 deletions

View File

@ -571,9 +571,10 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber); m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
#endif // QT_CONFIG(xcb_xlib) #endif // QT_CONFIG(xcb_xlib)
if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection))) if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection))) {
qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData()); qCWarning(lcQpaScreen, "QXcbConnection: Could not connect to display %s", m_displayName.constData());
return;
}
m_reader = new QXcbEventReader(this); m_reader = new QXcbEventReader(this);
m_reader->start(); m_reader->start();
@ -668,7 +669,7 @@ QXcbConnection::~QXcbConnection()
finalizeXInput2(); finalizeXInput2();
#endif #endif
if (m_reader->isRunning()) { if (m_reader && m_reader->isRunning()) {
sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION); sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION);
m_reader->wait(); m_reader->wait();
} }
@ -685,15 +686,22 @@ QXcbConnection::~QXcbConnection()
delete m_glIntegration; delete m_glIntegration;
if (isConnected()) {
#if QT_CONFIG(xcb_xlib) #if QT_CONFIG(xcb_xlib)
XCloseDisplay(static_cast<Display *>(m_xlib_display)); XCloseDisplay(static_cast<Display *>(m_xlib_display));
#else #else
xcb_disconnect(xcb_connection()); xcb_disconnect(xcb_connection());
#endif #endif
}
delete m_keyboard; delete m_keyboard;
} }
bool QXcbConnection::isConnected() const
{
return m_connection && !xcb_connection_has_error(m_connection);
}
QXcbScreen *QXcbConnection::primaryScreen() const QXcbScreen *QXcbConnection::primaryScreen() const
{ {
if (!m_screens.isEmpty()) { if (!m_screens.isEmpty()) {

View File

@ -388,6 +388,7 @@ public:
~QXcbConnection(); ~QXcbConnection();
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); } QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
bool isConnected() const;
const QList<QXcbVirtualDesktop *> &virtualDesktops() const { return m_virtualDesktops; } const QList<QXcbVirtualDesktop *> &virtualDesktops() const { return m_virtualDesktops; }
const QList<QXcbScreen *> &screens() const { return m_screens; } const QList<QXcbScreen *> &screens() const { return m_screens; }

View File

@ -178,12 +178,25 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
const int numParameters = parameters.size(); const int numParameters = parameters.size();
m_connections.reserve(1 + numParameters / 2); m_connections.reserve(1 + numParameters / 2);
m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName); auto conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName);
if (conn->isConnected())
m_connections << conn;
else
delete conn;
for (int i = 0; i < numParameters - 1; i += 2) { for (int i = 0; i < numParameters - 1; i += 2) {
qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()); conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData());
if (conn->isConnected())
m_connections << conn;
else
delete conn;
}
if (m_connections.isEmpty()) {
qCritical("Could not connect to any X display.");
exit(1);
} }
m_fontDatabase.reset(new QGenericUnixFontDatabase()); m_fontDatabase.reset(new QGenericUnixFontDatabase());