Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*dst_px in SDL_PremultiplyAlpha() is inaccessible when setting cursor under wayland - causing "Bus error" #9256

Closed
ASong5 opened this issue Mar 12, 2024 · 12 comments · Fixed by #9258
Assignees
Milestone

Comments

@ASong5
Copy link

ASong5 commented Mar 12, 2024

System Specs:

           `.:/ossyyyysso/:.               pundrew@pundrew-desktop 
        .:oyyyyyyyyyyyyyyyyyyo:`           ----------------------- 
      -oyyyyyyyodMMyyyyyyyysyyyyo-         OS: Kubuntu 23.10 x86_64 
    -syyyyyyyyyydMMyoyyyydmMMyyyyys-       Kernel: 6.5.0-25-generic 
   oyyysdMysyyyydMMMMMMMMMMMMMyyyyyyyo     Uptime: 1 hour, 58 mins 
 `oyyyydMMMMysyysoooooodMMMMyyyyyyyyyo`    Packages: 3120 (dpkg), 42 (flatpak), 8 (snap) 
 oyyyyyydMMMMyyyyyyyyyyyysdMMysssssyyyo    Shell: bash 5.2.15 
-yyyyyyyydMysyyyyyyyyyyyyyysdMMMMMysyyy-   Resolution: 1920x1080 
oyyyysoodMyyyyyyyyyyyyyyyyyyydMMMMysyyyo   DE: Plasma 5.27.8 
yyysdMMMMMyyyyyyyyyyyyyyyyyyysosyyyyyyyy   WM: kwin 
yyysdMMMMMyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy   WM Theme: Sweet-Dark 
oyyyyysosdyyyyyyyyyyyyyyyyyyydMMMMysyyyo   Theme: [Plasma], Breeze [GTK2/3] 
-yyyyyyyydMysyyyyyyyyyyyyyysdMMMMMysyyy-   Icons: [Plasma], candy-icons [GTK2/3] 
 oyyyyyydMMMysyyyyyyyyyyysdMMyoyyyoyyyo    Terminal: konsole 
 `oyyyydMMMysyyyoooooodMMMMyoyyyyyyyyo     Terminal Font: Hack Nerd Font 12 
   oyyysyyoyyyysdMMMMMMMMMMMyyyyyyyyo      CPU: AMD Ryzen 5 3600 (12) @ 3.600GHz 
    -syyyyyyyyydMMMysyyydMMMysyyyys-       GPU: AMD ATI Radeon RX 5600 OEM/5600 XT / 5700/5700 XT 
      -oyyyyyyydMMyyyyyyysosyyyyo-         Memory: 6903MiB / 15902MiB 
        ./oyyyyyyyyyyyyyyyyyyo/.
           `.:/oosyyyysso/:.`                                      

                                           SDL version 2.28.3

I am not familiar at all with the inner-workings of SDL, though I interact a lot with it indirectly via pygame, which is a python wrapper for many SDL functions.

When I try to set a cursor to some surface, I get a fatal "Bus error". This doesn't happen all the time, and restarting my PC always fixes it. However, the issue returns unexpectedly, and seemingly at random.

Here is a minimal reproducible example in pygame:

import pygame

pygame.init()
screen = pygame.display.set_mode((720, 720))

pygame.mouse.set_cursor((0, 0), pygame.Surface((30, 30)))

The following is the backtrace of the program:

Thread 1 "python3.11" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimised out>) at ./nptl/pthread_kill.c:44
Download failed: Invalid argument.  Continuing without source file ./nptl/./nptl/pthread_kill.c.                                                                                             
44      ./nptl/pthread_kill.c: No such file or directory.
(gdb) backtrace
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimised out>) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=<optimised out>) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=<optimised out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7c428e6 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7c268b7 in __GI_abort () at ./stdlib/abort.c:79
#5  0x0000000000424f47 in fatal_error_exit (status=-1) at ../Python/pylifecycle.c:2626
#6  fatal_error (fd=<optimised out>, header=<optimised out>, prefix=<optimised out>, msg=<optimised out>, status=-1) at ../Python/pylifecycle.c:2737
#7  0x00000000004b87d5 in _Py_FatalErrorFunc (func=func@entry=0x7ffff7fafb20 <__func__.1> "pygame_parachute", msg=msg@entry=0x7ffff7faf092 "(pygame parachute) Bus Error")
    at ../Python/pylifecycle.c:2823
#8  0x00007ffff7facb66 in pygame_parachute (sig=7) at src_c/base.c:2122
#9  0x00007ffff7c42990 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6
#10 0x00007ffff70e4715 in SDL_PremultiplyAlpha_REAL
    (width=72, height=81, src_format=<optimised out>, src=0x1c3d8c0, src_pitch=288, dst_format=<optimised out>, dst=0x7ffff00f9000, dst_pitch=288)
    at /usr/src/libsdl2-2.28.3+dfsg-2/src/video/SDL_surface.c:1548
#11 0x00007ffff71254ab in Wayland_CreateCursor (surface=0x1afa8d0, hot_x=36, hot_y=36) at /usr/src/libsdl2-2.28.3+dfsg-2/src/video/wayland/SDL_waylandmouse.c:406
#12 0x00007ffff705a9c4 in SDL_CreateColorCursor_REAL (surface=0x1afa8d0, hot_x=36, hot_y=36) at /usr/src/libsdl2-2.28.3+dfsg-2/src/events/SDL_mouse.c:1294
#13 0x00007ffff61400db in _set_color_cursor (surfobj=0x7ffff499c970, spoty=<optimised out>, spotx=<optimised out>) at src_c/mouse.c:373
#14 mouse_set_cursor (self=<optimised out>, args=0xa56698 <_PyRuntime+58904>, kwds=<optimised out>) at src_c/mouse.c:448
#15 0x0000000000512776 in cfunction_call (func=0x7ffff62236a0, args=<optimised out>, kwargs=<optimised out>) at ../Objects/methodobject.c:542
#16 0x00000000005338ae in _PyObject_Call (kwargs=<optimised out>, args=0xa56698 <_PyRuntime+58904>, callable=0x7ffff62236a0, tstate=0xa70a38 <_PyRuntime+166328>) at ../Objects/call.c:343
#17 PyObject_Call (callable=0x7ffff62236a0, args=0xa56698 <_PyRuntime+58904>, kwargs=<optimised out>) at ../Objects/call.c:355
#18 0x00000000004fe3cb in do_call_core (use_tracing=<optimised out>, kwdict=0x7ffff49be900, callargs=0xa56698 <_PyRuntime+58904>, func=0x7ffff62236a0, tstate=<optimised out>)
    at ../Python/ceval.c:7315
#19 _PyEval_EvalFrameDefault (tstate=<optimised out>, frame=<optimised out>, throwflag=<optimised out>) at ../Python/ceval.c:5367
#20 0x00000000005d99bf in _PyEval_EvalFrame (throwflag=0, frame=0x7ffff7fb3020, tstate=0xa70a38 <_PyRuntime+166328>) at ../Include/internal/pycore_ceval.h:73
#21 _PyEval_Vector (args=0x0, argcount=0, kwnames=0x0, locals=<optimised out>, func=0x7ffff7215b20, tstate=0xa70a38 <_PyRuntime+166328>) at ../Python/ceval.c:6425
#22 PyEval_EvalCode (co=0x7ffff73c03b0, globals=<optimised out>, locals=<optimised out>) at ../Python/ceval.c:1140
#23 0x00000000005f7fc7 in run_eval_code_obj (tstate=0xa70a38 <_PyRuntime+166328>, co=0x7ffff73c03b0, globals=0x7ffff73f3680, locals=0x7ffff73f3680) at ../Python/pythonrun.c:1710
#24 0x00000000005f49c3 in run_mod (mod=<optimised out>, filename=<optimised out>, globals=0x7ffff73f3680, locals=0x7ffff73f3680, flags=<optimised out>, arena=<optimised out>)
    at ../Python/pythonrun.c:1731
#25 0x0000000000608896 in pyrun_file (fp=0xadc9d0, filename=0x7ffff732cd50, start=<optimised out>, globals=0x7ffff73f3680, locals=0x7ffff73f3680, closeit=1, flags=0x7fffffffd8c8)
    at ../Python/pythonrun.c:1626
#26 0x00000000006085e1 in _PyRun_SimpleFileObject (fp=fp@entry=0xadc9d0, filename=filename@entry=0x7ffff732cd50, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffd8c8)
    at ../Python/pythonrun.c:440
#27 0x00000000006083b4 in _PyRun_AnyFileObject (fp=0xadc9d0, filename=filename@entry=0x7ffff732cd50, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffd8c8) at ../Python/pythonrun.c:79
#28 0x000000000060690f in pymain_run_file_obj (skip_source_first_line=0, filename=0x7ffff732cd50, program_name=0x7ffff73963b0) at ../Modules/main.c:360
#29 pymain_run_file (config=0xa56a80 <_PyRuntime+59904>) at ../Modules/main.c:379
#30 pymain_run_python (exitcode=0x7fffffffd8c4) at ../Modules/main.c:601
#31 Py_RunMain () at ../Modules/main.c:680
#32 0x00000000005cb9db in Py_BytesMain (argc=<optimised out>, argv=<optimised out>) at ../Modules/main.c:734
#33 0x00007ffff7c28150 in __libc_start_call_main (main=main@entry=0x5cb940 <main>, argc=argc@entry=2, argv=argv@entry=0x7fffffffdaf8) at ../sysdeps/nptl/libc_start_call_main.h:58
#34 0x00007ffff7c28209 in __libc_start_main_impl
    (main=0x5cb940 <main>, argc=2, argv=0x7fffffffdaf8, init=<optimised out>, fini=<optimised out>, rtld_fini=<optimised out>, stack_end=0x7fffffffdae8) at ../csu/libc-start.c:360
#35 0x00000000005cb875 in _start ()

I did some digging with gdb, and it seems the exception is raised here on this line:

*dst_px++ = dstpixel;

which is called here:

SDL_PremultiplyAlpha(surface->w, surface->h,
surface->format->format, surface->pixels, surface->pitch,
SDL_PIXELFORMAT_ARGB8888, data->shm_data, surface->w * 4);

If I am understanding correctly, data->shm_data, when casted to a Uint32 * is not accessible. This corresponds with the following gdb output:

Thread 1 "python3.11" hit Breakpoint 3, Wayland_CreateCursor (surface=0x1922be0, hot_x=36, hot_y=41) at /usr/src/libsdl2-2.28.3+dfsg-2/src/video/wayland/SDL_waylandmouse.c:406
406             SDL_PremultiplyAlpha(surface->w, surface->h,
(gdb) s
SDL_PremultiplyAlpha_REAL (width=72, height=82, src_format=372645892, src=0x1c5a4e0, src_pitch=288, dst_format=372645892, dst=0x7ffff00f9000, dst_pitch=288)
    at /usr/src/libsdl2-2.28.3+dfsg-2/src/video/SDL_surface.c:1507
1507    {
(gdb) s
1514        if (src == NULL) {
(gdb) 
1517        if (!src_pitch) {
(gdb) 
1520        if (dst == NULL) {
(gdb) 
1523        if (!dst_pitch) {
(gdb) 
1526        if (src_format != SDL_PIXELFORMAT_ARGB8888) {
(gdb) 
1529        if (dst_format != SDL_PIXELFORMAT_ARGB8888) {
(gdb) 
1533        while (height--) {
(gdb) 
1536            for (c = width; c; --c) {
(gdb) 
1538                srcpixel = *src_px++;
(gdb) p srcpixel 
$7 = <optimised out>
(gdb) p src_px 
$8 = (const Uint32 *) 0x1c5a4e4
(gdb) p *src_px 
$9 = 0
(gdb) s
1539                RGBA_FROM_ARGB8888(srcpixel, srcR, srcG, srcB, srcA);
(gdb) 

Thread 1 "python3.11" hit Breakpoint 2, SDL_PremultiplyAlpha_REAL (width=72, height=81, src_format=<optimised out>, src=0x1c5a4e0, src_pitch=288, dst_format=<optimised out>, 
    dst=0x7ffff00f9000, dst_pitch=288) at /usr/src/libsdl2-2.28.3+dfsg-2/src/video/SDL_surface.c:1549
1549                *dst_px++ = dstpixel;
(gdb) p dstpixel 
$10 = 0
(gdb) p dst_px
$11 = (Uint32 *) 0x7ffff00f9004
(gdb) p *dst_px
Cannot access memory at address 0x7ffff00f9004

I suspect this to be a wayland/kwin/kwin-bismuth issue, but I am not confident in troubleshooting this enough to be sure.

Here is a relevant part of journalctl output:

Mar 12 02:48:11 pundrew-desktop systemd[1]: systemd-coredump@1-188357-0.service: Deactivated successfully.
Mar 12 02:48:11 pundrew-desktop systemd-coredump[188358]: [🡕] Process 187945 (python3.11) of user 1000 dumped core.
                                                          
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/_freetype.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/system.cpython-311-x86_64-linux-gnu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/scrap.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mixer.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mixer_music.cpython-311-x86_64-linu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/font.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/transform.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/pixelarray.cpython-311-x86_64-linux>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/pixelcopy.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mask.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/time.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mouse.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/key.cpython-311-x86_64-linux-gnu.so>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/imageext.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/image.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/joystick.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/event.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/draw.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/window.cpython-311-x86_64-linux-gnu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/surface.cpython-311-x86_64-linux-gn>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/display.cpython-311-x86_64-linux-gn>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/math.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/bufferproxy.cpython-311-x86_64-linu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/color.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/rect.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/surflock.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/rwobject.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/constants.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/base.cpython-311-x86_64-linux-gnu.s>
                                                          Module libsystemd.so.0 from deb systemd-253.5-1ubuntu6.1.amd64
                                                          Stack trace of thread 187945:
                                                          #0  0x00007ab772a99a1b __pthread_kill_implementation (libc.so.6 + 0x99a1b)
                                                          #1  0x00007ab772a428e6 __GI_raise (libc.so.6 + 0x428e6)
                                                          #2  0x00007ab772a268b7 __GI_abort (libc.so.6 + 0x268b7)
                                                          #3  0x0000000000424f47 n/a (python3.11 + 0x24f47)
                                                          #4  0x00000000004b87d5 _Py_FatalErrorFunc (python3.11 + 0xb87d5)
                                                          #5  0x00007ab772d71b66 n/a (/home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/base.cpython-3>
                                                          ELF object binary architecture: AMD x86-64
Mar 12 02:48:11 pundrew-desktop systemd[1]: Started systemd-coredump@1-188357-0.service - Process Core Dump (PID 188357/UID 0).
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrange
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: [Controller#onWindowRemoved] Window removed: Window(KWin(undefined.map_creator.py))
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: Client is ok, can manage. Bind events now...
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrange
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: onWindowAdded,[object Object]
Mar 12 02:48:11 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: Client added: KWin::XdgToplevelWindow(0x5c848b7b1750)
Mar 12 02:48:10 pundrew-desktop rtkit-daemon[1081]: Supervising 11 threads of 8 processes of 1 users.
Mar 12 02:48:10 pundrew-desktop rtkit-daemon[1081]: Successfully made thread 188319 of process 187945 owned by '1000' high priority at nice level -15.
Mar 12 02:47:58 pundrew-desktop systemd[1]: systemd-coredump@0-187396-0.service: Deactivated successfully.
Mar 12 02:47:58 pundrew-desktop systemd-coredump[187404]: [🡕] Process 186428 (python3.11) of user 1000 dumped core.
                                                          
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/_freetype.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/system.cpython-311-x86_64-linux-gnu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/scrap.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mixer.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mixer_music.cpython-311-x86_64-linu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/transform.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/pixelarray.cpython-311-x86_64-linux>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/font.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/pixelcopy.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mask.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/time.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/mouse.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/key.cpython-311-x86_64-linux-gnu.so>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/imageext.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/image.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/joystick.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/event.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/draw.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/window.cpython-311-x86_64-linux-gnu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/surface.cpython-311-x86_64-linux-gn>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/display.cpython-311-x86_64-linux-gn>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/math.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/bufferproxy.cpython-311-x86_64-linu>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/color.cpython-311-x86_64-linux-gnu.>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/rect.cpython-311-x86_64-linux-gnu.s>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/surflock.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/rwobject.cpython-311-x86_64-linux-g>
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/constants.cpython-311-x86_64-linux->
                                                          Module /home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/base.cpython-311-x86_64-linux-gnu.s>
                                                          Module libsystemd.so.0 from deb systemd-253.5-1ubuntu6.1.amd64
                                                          Stack trace of thread 186428:
                                                          #0  0x0000748e9f299a1b __pthread_kill_implementation (libc.so.6 + 0x99a1b)
                                                          #1  0x0000748e9f2428e6 __GI_raise (libc.so.6 + 0x428e6)
                                                          #2  0x0000748e9f2268b7 __GI_abort (libc.so.6 + 0x268b7)
                                                          #3  0x0000000000424f47 n/a (python3.11 + 0x24f47)
                                                          #4  0x00000000004b87d5 _Py_FatalErrorFunc (python3.11 + 0xb87d5)
                                                          #5  0x0000748e9f5b9b66 n/a (/home/pundrew/git/github/Projects/BnBClone/venv3.11/lib/python3.11/site-packages/pygame/base.cpython-3>
                                                          ELF object binary architecture: AMD x86-64
Mar 12 02:47:57 pundrew-desktop systemd[1]: Started systemd-coredump@0-187396-0.service - Process Core Dump (PID 187396/UID 0).
Mar 12 02:47:57 pundrew-desktop systemd[1]: Created slice system-systemd\x2dcoredump.slice - Slice /system/systemd-coredump.
Mar 12 02:47:57 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:47:57 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:47:57 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrange
Mar 12 02:47:57 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: [Controller#onWindowRemoved] Window removed: Window(KWin(undefined.map_creator.py))
Mar 12 02:47:47 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: Client is ok, can manage. Bind events now...
Mar 12 02:47:47 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:47:47 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrangeScreen/finished,[object Object]
Mar 12 02:47:47 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: arrange
Mar 12 02:47:47 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: onWindowAdded,[object Object]
Mar 12 02:47:47 pundrew-desktop kwin_wayland_wrapper[1157]: org.kde.bismuth: Client added: KWin::XdgToplevelWindow(0x5c848b7b1750)

If anyone could help me troubleshoot this, I would appreciate it.

@slouken slouken added this to the 2.32.0 milestone Mar 12, 2024
@slouken
Copy link
Collaborator

slouken commented Mar 12, 2024

@Kontrabant, why would shared memory generate a bus error here?

@Kontrabant
Copy link
Contributor

Kontrabant commented Mar 12, 2024

Two possibilities offhand:

  • The filesystem where the temporary file was created (XDG_RUNTIME_DIR) runs out of space
  • A call to ftruncate() to set the file size runs asynchronously internally and isn't actually completed when it returns

To see if it is the latter issue, you can try adding an fsync() after the ftruncate() call here:
https://github.com/libsdl-org/SDL/blob/d79f8652510b8bd1f89c90be2ab65fc8940056eb/src/video/wayland/SDL_waylandmouse.c#L369C1-L372C6

Both of these issues resulted in similar problems for others at some point. We should probably use memfd_create(), if available, before trying to open a real file to avoid potential problems like this.

@Kontrabant
Copy link
Contributor

I'm betting that it's the no space issue. The way this works now, a temporary file is created and the size is set with ftruncate(), which doesn't return an error if there is insufficient space for the requested file size. I'm modifying this to open the temporary file with memfd_create(), when available, so it will reside entirely in memory, and using posix_fallocate() instead of ftruncate(), when available, to set the initial size, as it will return an ENOSPC error instead of succeeding and allowing a SIGBUS fault to occur when trying to access the unbacked mmap-ed memory.

These functions aren't 100% portable (the more niche BSDs may lack them), but the existing codepath still exists as a fallback.

@ASong5
Copy link
Author

ASong5 commented Mar 12, 2024

I'm betting that it's the no space issue. The way this works now, a temporary file is created and the size is set with ftruncate(), which doesn't return an error if there is insufficient space for the requested file size. I'm modifying this to open the temporary file with memfd_create(), when available, so it will reside entirely in memory, and using posix_fallocate() instead of ftruncate(), when available, to set the initial size, as it will return an ENOSPC error instead of succeeding and allowing a SIGBUS fault to occur when trying to access the unbacked mmap-ed memory.

These functions aren't 100% portable (the more niche BSDs may lack them), but the existing codepath still exists as a fallback.

Hey so I think you are right that it is the no space issue. When I run my pygame program, if any of the code uses pygame.mouse.set_cursor (which in turn calls the appropriate SDL equivalent), a very large amount of "sdl-shared-xxxxx" files are created, and it quickly fills up the tmpfs (XDG_RUNTIME_DIR), as shown below:

.rw------- 24k pundrew 12 Mar 18:27 sdl-shared-zzFchm
.rw------- 24k pundrew 12 Mar 18:28 sdl-shared-ZZKvB8
.rw------- 24k pundrew 12 Mar 18:27 sdl-shared-zzkyYC
.rw------- 24k pundrew 12 Mar 18:27 sdl-shared-ZZlDmb
.rw------- 24k pundrew 12 Mar 18:27 sdl-shared-ZzSOvG
.rw------- 24k pundrew 12 Mar 18:27 sdl-shared-zzSSFN
.rw------- 24k pundrew 12 Mar 18:25 sdl-shared-zZT3VF
.rw------- 24k pundrew 12 Mar 18:28 sdl-shared-ZZTQtq
.rw------- 24k pundrew 12 Mar 18:27 sdl-shared-ZZuAOn
.rw------- 24k pundrew 12 Mar 18:28 sdl-shared-ZZvd7m
...
ls /run/user/1000 | grep sdl-shared | wc -l
  14912   14912  268416
df -h /run/user/1000
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           1.6G  351M  1.3G  23% /run/user/1000

The files are not deleted when the program closes (I'm assuming they should be, though I'm not entirely sure how tmpfs works (edit: after some research it seems like they are only removed when the user session ends)). I'm assuming this isn't normal behavior (correct me if I'm wrong). Is this an issue with pygame's implementation of set_cursor, or is related to SDL directly?

Thanks for looking into this.

@slime73
Copy link
Contributor

slime73 commented Mar 12, 2024

From looking at pygame's source, it seems to create a brand new SDL cursor object each time set_cursor is called. I imagine that's not very efficient if it's called every frame.. but it also does have code to free the previous one so any leak might not be in pygame itself.

@ASong5
Copy link
Author

ASong5 commented Mar 12, 2024

Alas, it was a case of user error...

I imagine that's not very efficient if it's called every frame.

That was exactly what I was doing... I had unwittingly put my calls to set_cursor() in my game loop, which explains this:

very large amount of "sdl-shared-xxxxx" files are created, and it quickly fills up the tmpfs (XDG_RUNTIME_DIR)

Sorry for the trouble..

@slime73
Copy link
Contributor

slime73 commented Mar 12, 2024

If pygame is cleaning up properly when calling set_cursor (which I think it is, but I didn't look too closely) then I'd still find it surprising that a bunch of resources build up like that rather than just one or even a small number that evens out over time.

@Kontrabant
Copy link
Contributor

No trouble at all. Actually, this uncovered some bad behavior on the SDL side. We should be more robust against this than we are, and shouldn't be leaking those temp files. I have some pending changes to fix this.

@ASong5
Copy link
Author

ASong5 commented Mar 12, 2024

If pygame is cleaning up properly when calling set_cursor (which I think it is, but I didn't look too closely) then I'd still find it surprising that a bunch of resources build up like that rather than just one or even a small number that evens out over time.

I don't know much about SDL at all from a technical perspective, but pygame's set_cursor() seems to be freeing the Cursor objects appropriately via SDL_FreeCursor(); however, I'd imagine shared memory files generated in $XDG_RUNTIME_DIR would need to be deleted explicitly (which I'm not even sure is something one should be doing to begin with), unless SDL_free handles that internally.

I also noticed this:

/* Not sure what's meant to happen to shm_data */
SDL_free(cursor->driverdata);
SDL_free(cursor);

which is probably relevant - seems the author also wasn't sure what to do with them.

@Kontrabant
Copy link
Contributor

Temp files being leaked is now fixed in SDL 2 and 3.

@slouken
Copy link
Collaborator

slouken commented Mar 13, 2024

And I cherry-picked to release-2.30.x, thanks!

@Kontrabant
Copy link
Contributor

The SDL2 autotools build needed to be updated with the checks for memfd_create() and posix_fallocate() as well. Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants