Package: libqt5gui5 Version: 5.15.4+dfsg-5 Severity: important Dear Maintainer,
When running some Qt-based applications, I get the following error, followed by a segmentation fault. Which, I believe is due to a bug in Qt. qt.qpa.xcb: xcb_shm_create_segment() can't be called for size 17178820624, maximumallowed size is 4294967295 This only happen on applications that (try to) show a splash screen, like fritzing and shortcut. And only happen on my machine that has a 4K monitor. Here's what I understand of what happen: The application tries to show a window for the splash screen. The method QXcbWindow::create() calls QXcbWindow::propagateSizeHints() which end up calling xcb_icccm_size_hints_set_base_size with a size of (-2, -2). We get these values because the window baseSize isn't initialized yet and HiDPI-scaled. These hints are then sent to the X server. Those values are then sent back to the application as some ConfigureNotify event (I believe) as a pair of uint16_t. This prompts Qt to try to reallocate an unreasonably large buffer to accomodate the "resized" window. Here are the few lines of logs obtained with QT_LOGGING_RULES='qt.qpa.*=true' right before the warning message that lead to a crash. qt.qpa.events: Event | XCB_PROPERTY_NOTIFY(28) | sequence: 402 qt.qpa.events: Event | XCB_PROPERTY_NOTIFY(28) | sequence: 402 qt.qpa.events: Event | XCB_CONFIGURE_NOTIFY(22) | sequence: 402 qt.qpa.xcb: [ QWidgetWindow(0x55751b9cc380, name="FSplashScreenClassWindow") ] creating shared memory 17178820624 bytes for QSize(65534, 65534) depth 24 bits 32 qt.qpa.xcb: xcb_shm_create_segment() can't be called for size 17178820624, maximumallowed size is 4294967295 I don't know exactly why this only happen on some very specific combinations of hardwares and softwares, but google tells me this bug affects several applications and are always related to 4K monitors. Could be also related to the window manager. I use fluxbox. I'm not sure why the window baseSize is uninitialized, but in any case, setting a negative base_size hint in QXcbWindow::propagateSizeHints() sounds definitely like a bad idea. Maybe the values should be checked before they are passed to xcb_icccm_size_hints_set_base_size, as is the case with other hint values in the same method. Unfortunately, I'm not well-versed enough in Qt to make an example program. However, just to check that this is the cause of the bug, I made a workaround using LD_PRELOAD to replace those negative hint values with zeros. I attach the source code. Compile with: gcc -o preload.so -shared -fPIC preload.c -ldl -Wl,--no-as-needed -lxcb-icccm Run with: LD_PRELOAD=./preload.so fritzing Best regards, Celelibi -- System Information: Debian Release: bookworm/sid APT prefers testing APT policy: (990, 'testing'), (500, 'testing-debug'), (500, 'unstable'), (500, 'stable') merged-usr: no Architecture: amd64 (x86_64) Kernel: Linux 5.18.0-4-amd64 (SMP w/8 CPU threads; PREEMPT) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_FIRMWARE_WORKAROUND, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages libqt5gui5 depends on: ii fontconfig 2.13.1-4.4 ii libc6 2.34-7 ii libdrm2 2.4.112-3 ii libegl1 1.5.0-1 ii libfontconfig1 2.13.1-4.4 ii libfreetype6 2.12.1+dfsg-3 ii libgbm1 22.2.0~rc3-1 ii libgcc-s1 12.2.0-1 ii libgl1 1.5.0-1 ii libglib2.0-0 2.73.3-3 ii libharfbuzz0b 2.7.4-1+b1 ii libice6 2:1.0.10-1 ii libinput10 1.21.0-1 ii libjpeg62-turbo 1:2.1.2-1 ii libmd4c0 0.4.8-1 ii libmtdev1 1.1.6-1 ii libpng16-16 1.6.37-5 ii libqt5core5a [qtbase-abi-5-15-4] 5.15.4+dfsg-5 ii libqt5dbus5 5.15.4+dfsg-5 ii libqt5network5 5.15.4+dfsg-5 ii libsm6 2:1.2.3-1 ii libstdc++6 12.2.0-1 ii libudev1 251.4-3 ii libx11-6 2:1.8.1-2 ii libx11-xcb1 2:1.8.1-2 ii libxcb-glx0 1.15-1 ii libxcb-icccm4 0.4.1-1.1 ii libxcb-image0 0.4.0-2 ii libxcb-keysyms1 0.4.0-1+b2 ii libxcb-randr0 1.15-1 ii libxcb-render-util0 0.3.9-1+b1 ii libxcb-render0 1.15-1 ii libxcb-shape0 1.15-1 ii libxcb-shm0 1.15-1 ii libxcb-sync1 1.15-1 ii libxcb-xfixes0 1.15-1 ii libxcb-xinerama0 1.15-1 ii libxcb-xinput0 1.15-1 ii libxcb-xkb1 1.15-1 ii libxcb1 1.15-1 ii libxkbcommon-x11-0 1.4.1-1 ii libxkbcommon0 1.4.1-1 ii libxrender1 1:0.9.10-1.1 ii zlib1g 1:1.2.11.dfsg-4.1 Versions of packages libqt5gui5 recommends: ii libqt5svg5 5.15.4-2 pn qt5-gtk-platformtheme <none> Versions of packages libqt5gui5 suggests: pn qt5-image-formats-plugins <none> pn qtwayland5 <none> -- no debconf information
/* gcc -o preload.so -shared -fPIC preload.c -ldl -Wl,--no-as-needed -lxcb-icccm */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <xcb/xcb_icccm.h> static void (*xcb_icccm_size_hints_set_base_size_orig)(xcb_size_hints_t *, int32_t, int32_t) = NULL; void xcb_icccm_size_hints_set_base_size(xcb_size_hints_t *hints, int32_t base_width, int32_t base_height) { printf("xcb_icccm_size_hints_set_base_size called with %d %d\n", base_width, base_height); if (xcb_icccm_size_hints_set_base_size_orig == NULL) { *(void **)&xcb_icccm_size_hints_set_base_size_orig = dlsym(RTLD_NEXT, "xcb_icccm_size_hints_set_base_size"); fprintf(stderr, "xcb_icccm_size_hints_set_base_size found at 0x%08lx\n", (uintptr_t)xcb_icccm_size_hints_set_base_size_orig); if (xcb_icccm_size_hints_set_base_size_orig == NULL) abort(); } if (base_width < 0) base_width = 0; if (base_height < 0) base_height = 0; xcb_icccm_size_hints_set_base_size_orig(hints, base_width, base_height); }