libsdl-org / sdl12-compat

An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes.
Other
193 stars 40 forks source link

btanks: segfault on exit #254

Closed smcv closed 1 year ago

smcv commented 1 year ago

Prerequisites:

To reproduce:

Start a level. Run around a bit (arrow keys, left Ctrl to shoot). Quit with Alt+F4.

Expected result: success

Actual result: real SDL 1.2 works. sdl12-compat basically works, but on exit it segfaults while unloading SDL 2:

(gdb) thread apply all bt

Thread 2 (Thread 0x7fac23cefb80 (LWP 15486)):
#0  0x00007fac249def87 in __GI_munmap () at ../sysdeps/unix/syscall-template.S:117
#1  0x00007fac249d1fad in _dl_unmap_segments (l=l@entry=0x555556a4dd40) at ./dl-unmap-segments.h:32
#2  _dl_unmap (map=map@entry=0x555556a4dd40) at ../sysdeps/x86_64/tlsdesc.c:31
#3  0x00007fac249bea64 in _dl_close_worker (map=map@entry=0x555556a4aee0, force=force@entry=false) at ./elf/dl-close.c:657
#4  0x00007fac249bf047 in _dl_close (_map=0x555556a4aee0) at ./elf/dl-close.c:818
#5  0x00007fac23f50e70 in __GI__dl_catch_exception (exception=exception@entry=0x7ffdc6c64cf0, operate=<optimized out>, args=<optimized out>) at ./elf/dl-error-skeleton.c:208
#6  0x00007fac23f50f2f in __GI__dl_catch_error (objname=0x7ffdc6c64d48, errstring=0x7ffdc6c64d50, mallocedp=0x7ffdc6c64d47, operate=<optimized out>, args=<optimized out>) at ./elf/dl-error-skeleton.c:227
#7  0x00007fac23e834c6 in _dlerror_run (operate=<optimized out>, args=<optimized out>) at ./dlfcn/dlerror.c:138
#8  0x00007fac23e83246 in __dlclose (handle=<optimized out>) at ./dlfcn/dlclose.c:31
#9  0x00007fac24855514 in UnloadSDL20 () at ./src/SDL12_compat.c:1176
#10 0x00007fac249c1aae in _dl_fini () at ./elf/dl-fini.c:142
#11 0x00007fac23e3ffb5 in __run_exit_handlers (status=0, listp=0x7fac23ff4818 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at ./stdlib/exit.c:113
#12 0x00007fac23e4012a in __GI_exit (status=<optimized out>) at ./stdlib/exit.c:143
#13 0x00007fac23e29211 in __libc_start_call_main (main=main@entry=0x7fac249b85f0, argc=argc@entry=1, argv=argv@entry=0x7ffdc6c652c8) at ../sysdeps/nptl/libc_start_call_main.h:74
#14 0x00007fac23e292bc in __libc_start_main_impl (main=0x7fac249b85f0, argc=1, argv=0x7ffdc6c652c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffdc6c652b8) at ../csu/libc-start.c:389
#15 0x00007fac249b87ba in ?? ()
#16 0x00007ffdc6c652b8 in ?? ()
#17 0x000000000000009c in ?? ()
#18 0x0000000000000001 in ?? ()
#19 0x00007ffdc6c673df in ?? ()
#20 0x0000000000000000 in ?? ()

Thread 1 (Thread 0x7fac0e7fc640 (LWP 15502)):
#0  0x0000000000000000 in ?? ()
#1  0x00007fac249721b7 in sdlx::Mutex::lock (this=<optimized out>) at sdlx/mutex.cpp:42
#2  0x00007fac249724ac in sdlx::AutoMutex::AutoMutex (this=0x7fac0e7fb750, m=..., lock=<optimized out>) at sdlx/mutex.cpp:56
#3  0x00007fac2466f95f in Monitor::run (this=<optimized out>) at engine/net/monitor.cpp:371
#4  0x00007fac234d7e65 in ?? ()
#5  0x00007fac0e7fc640 in ?? ()
#6  0x0000000000000000 in ?? ()

It would probably be safer to never dlclose() SDL 2 - unloading libraries basically doesn't work unless the library and all its dependencies were carefully designed to make it possible, and in any case if we're unloading SDL then we're almost certainly going to exit shortly anyway.

smcv commented 1 year ago

Correction, 1.2.58 has this bug but I couldn't reproduce it with https://github.com/libsdl-org/sdl12-compat/commit/63e4393d89482a87bfc91f849c6f32584cc7b21d.