On Sun Nov 13, 2022 at 08:37:55PM +0100, Rafael Sadowski wrote: > I don't know if this has worked in the past, but when debugging some Qt > applications I saw the following debug messages: > > $ gwenview > qt.qpa.xcb: Has MIT-SHM : true > qt.qpa.xcb: Has MIT-SHM FD : true > qt.qpa.xcb: xcb_shm_attach() failed > qt.qpa.xcb: failed to create System V shared memory segment (remote X11 > connection?), disabling SHM > qt.qpa.xcb: Using XInput version 2.2 > qt.qpa.screen: Output DP-1 is not connected > qt.qpa.screen: Output HDMI-1 is not connected > > The code that fails is here. xcb_shm_attach_checked and/or > xcb_request_check failed with all my Qt applications. > > pobj/qtbase-5.15.6/qtbase-everywhere-src-5.15.6/src/plugins/platforms/xcb/qxcbbackingstore.cpp > > bool QXcbBackingStoreImage::createSystemVShmSegment(xcb_connection_t *c, > size_t segmentSize, > xcb_shm_segment_info_t > *shmInfo) > { > const int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0x1C0); > if (id == -1) { > qCWarning(lcQpaXcb, "shmget() failed (%d: %s) for size %zu", errno, > strerror(errno), segmentSize); > return false; > } > > void *addr = shmat(id, nullptr, 0); > if (addr == (void *)-1) { > qCWarning(lcQpaXcb, "shmat() failed (%d: %s) for id %d", errno, > strerror(errno), id); > return false; > } > > if (shmctl(id, IPC_RMID, nullptr) == -1) > qCWarning(lcQpaXcb, "Error while marking the shared memory segment to > be destroyed"); > > const auto seg = xcb_generate_id(c); > auto cookie = xcb_shm_attach_checked(c, seg, id, false); > auto *error = xcb_request_check(c, cookie); > if (error) { > qCWarning(lcQpaXcb(), "xcb_shm_attach() failed"); > free(error); > if (shmdt(addr) == -1) > qCWarning(lcQpaXcb, "shmdt() failed (%d: %s) for %p", errno, > strerror(errno), addr); > return false; > > > If you want to test it run any Qt application with > QT_LOGGING_RULES="qt.qpa.xcb.debug=true" exported. > > Should SHM with XCB generally work on OpenBSD? > > Rafael >
Okay I tried to isolate that issue form Qt and unfortunately I can reproduce the same issue. The following code only works with "DISPLAY:0" and xcb_connect. Which is wired, isn't? - xcb_connect(3): - display_name = "DISPLAY:0" - works - display_name = ":0" fails with xcb_shm_attach_checked - display_name = NULL fails with xcb_shm_attach_checked - XOpenDisplay(3): - display_name = "DISPLAY:0" - segmentation fault - display_name = ":0" fails with xcb_shm_attach_checked - display_name = NULL fails with xcb_shm_attach_checked Qt use XOpenDisplay(3) to connect to the XServer. Unfortunately, I can't find a solution with XOpenDisplay(3) which works with SHM. Someone has an idea or can confirm my issue? Here is my "small" test case: // cc -O2 -pipe -std=c99 -I/usr/X11R6/include/xcb -I/usr/X11R6/include -L/usr/X11R6/lib \ // -lxcb-shm -lxcb -lX11-xcb -lX11 xcb_shm_attach.c #include <xcb.h> #include <xcb/shm.h> #include <xcb/xcb_image.h> #include <xcb/render.h> #include <xcb/xcb_renderutil.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/mman.h> #include <stdio.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <X11/Xlib.h> #include <X11/Xlib-xcb.h> #include <X11/Xlibint.h> #include <X11/Xutil.h> int main(int argc, char *argv[]) { // create connection to X11 server /** * displayname = "DISPLAY:0" work with xcb_shm_attach_checked * displayname = ":0" NOT work with xcb_shm_attach_checked * displayname = NULL NOT work with xcb_shm_attach_checked */ /* int screen = 0; xcb_connection_t* c = xcb_connect("DISPLAY:0", &screen); // is the only one that works with xcb_shm_attach_checked if(c == NULL) { printf("xcb_connect"); return -1; } */ /** * displayname = "DISPLAY:0" segmentation fault * displayname = ":0" NOT work with xcb_shm_attach_checked * displayname = NULL NOT work with xcb_shm_attach_checked */ Display *dpy = XOpenDisplay(NULL); xcb_connection_t* c = XGetXCBConnection(dpy); struct xcb_shm_segment_info_t *shmInfo; size_t segmentSize = 1800; const int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600); if (id == -1) { printf("shmget"); return -1; } void *addr = shmat(id, NULL, 0); if (addr == (void *)-1) { printf("shmat"); return -1; } if (shmctl(id, IPC_RMID, NULL) == -1) { printf("shmctl"); return -1; } const uint32_t seg = xcb_generate_id(c); xcb_void_cookie_t cookie = xcb_shm_attach_checked(c, seg, id, 1); xcb_generic_error_t* error = xcb_request_check(c, cookie); if (error) { fprintf(stderr, "xcb_shm_attach_checked Error %d\n", error->error_code); free(error); if (shmdt(addr) == -1) { printf("xcb_request_check 2"); return -1; } return -1; } else if (!shmInfo) { printf("xcb_shm_detach\n"); xcb_shm_detach(c, seg); } if (shmInfo) { shmInfo->shmseg = seg; shmInfo->shmid = id; } printf("worked"); return 0; }