--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp 2018-01-26 08:34:43.771873100 +0100 +++ b7src/plugins/platforms/xcb/qxcbbackingstore.cpp 2018-01-26 08:40:26.192328800 +0100 @@ -84,6 +84,7 @@ private: void destroy(); + static bool isShmSupported(); void ensureGC(xcb_drawable_t dst); void flushPixmap(const QRegion ®ion); @@ -143,6 +144,44 @@ QImage *m_image; }; +static bool shmNotSupported = false; + +static void +SigSysHandler(int signo) +{ + shmNotSupported = true; +} + +bool +QXcbShmImage::isShmSupported() +{ + static bool checked = false; + if (!checked) + { + void (*oldHandler)(int); + int shmid = -1; + + /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ + oldHandler = signal(SIGSYS, SigSysHandler); + + shmNotSupported = false; + shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); + if (shmid != -1) + { + /* Successful allocation - clean up */ + shmctl(shmid, IPC_RMID, NULL); + } + else + { + /* Allocation failed */ + shmNotSupported = true; + } + signal(SIGSYS, oldHandler); + checked = true; + } + return (!shmNotSupported); +} + QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format) : QXcbObject(screen->connection()) , m_graphics_buffer(Q_NULLPTR) @@ -167,7 +206,9 @@ if (!segmentSize) return; - int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600); + int id = -1; + if (isShmSupported()) + id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600); if (id == -1) { qWarning("QXcbShmImage: shmget() failed (%d: %s) for size %d (%dx%d)", errno, strerror(errno), segmentSize, size.width(), size.height());