View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0010270 | Dwarf Fortress | Technical -- Rendering | public | 2017-07-25 16:25 | 2017-07-28 11:10 |
Reporter | Muffindrake | Assigned To | |||
Priority | high | Severity | crash | Reproducibility | always |
Status | new | Resolution | open | ||
Platform | Linux x86_64 | OS | Gentoo Linux | ||
Product Version | 0.43.05 | ||||
Summary | 0010270: libgraphics.so dlopen()ing libncursesw.so.5 instead of .so.6 can segfault on some systems with PRINT_MODE:TEXT | ||||
Description | I tried to launch DF in text mode after some time and find that it crashes instantly. After some time spent researching the problem, I see that the game and libgraphics.so are linked to libncurses(w).so.6, while libgraphics.so tries to dlopen .so.5. Both ncurses 5 and 6 are installed at the same time on this machine (slotted), as per standard gentoo repo. The crash doesn't occur if a symlink is used to trick it into thinking it found .so.5, despite it being .so.6, hence it seems that the wrong version is being opened in libgraphics. The library also tried to dlopen libncursesw.so (which it does try if I uninstall ncurses 5 from the system), but inexplicably fails here as it doesn't seem to be a symlink here but an LD script and proclaims "Didn't find any flavor of libncursesw, attempting libncurses" and then "Unable to open any flavor of libncurses!" before exiting cleanly. Again, a symlink in /lib/ (or df/libs) with that name pointing to the right shared object resolves the problem. If that symlink points to ncurses 5 (.so.5), it crashes. TL;DR: Add some lines in g_src/renderer_curses.cpp Patch: --- a/g_src/renderer_curses.cpp +++ b/g_src/renderer_curses.cpp @@ -294,7 +294,7 @@ extern "C" { if (!stub_initialized) { stub_initialized = true; // We prefer libncursesw, but we'll accept libncurses if we have to + handle = dlopen("libncursesw.so.6", RTLD_LAZY); + if (handle) goto opened; handle = dlopen("libncursesw.so.5", RTLD_LAZY); if (handle) goto opened; handle = dlopen("libncursesw.so", RTLD_LAZY); if (handle) goto opened; @@ -302,7 +302,7 @@ extern "C" { sleep(5); handle = dlopen("libncurses.dylib", RTLD_LAZY); if (handle) goto opened; + handle = dlopen("libncurses.so.6", RTLD_LAZY); + if (handle) goto opened; handle = dlopen("libncurses.so.5", RTLD_LAZY); if (handle) goto opened; handle = dlopen("libncurses.so", RTLD_LAZY); if (handle) goto opened; | ||||
Steps To Reproduce | Have libncurses-5 installed Launch DF in PRINT_MODE:TEXT, perhaps put a symlink in df/libs named libncursesw.so.6 pointing to the installed (/usr)/lib/libncurses.so.5 | ||||
Additional Information | Core was generated by `./libs/Dwarf_Fortress'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x00007f674e864d07 in init_pair () from /usr/lib64/libncursesw.so.5 [...] (gdb) where #0 0x00007f674e864d07 in init_pair () from /usr/lib64/libncursesw.so.5 0000001 0x00007f676452dfda in init_curses () from /opt/dwarf-fortress/libs/libgraphics.so 0000002 0x00007f6764533fed in enablerst::loop(std::string) () from /opt/dwarf-fortress/libs/libgraphics.so 0000003 0x00007f67645281c4 in main () from /opt/dwarf-fortress/libs/libgraphics.so 0000004 0x00007f676390311a in __libc_start_main () from /lib64/libc.so.6 0000005 0x0000000000408f1f in ?? () | ||||
Tags | No tags attached. | ||||
|
As I pointed out on IRC, libgraphics is supposed to use ncurses 5. That part hasn't changed significantly in ages (since around 2010). I'm not sure why it's claiming to link to ncurses 6, but I imagine that's part of the build process. All of the ncurses interface is set up with dlopen()/dlsym(), not dynamic linking. Since some systems are distributing ncurses 6, but some still have ncurses 5, a better patch would check for ncurses 6 without dropping support for ncurses 5. I updated the patch above to do that. |
Date Modified | Username | Field | Change |
---|---|---|---|
2017-07-25 16:25 | Muffindrake | New Issue | |
2017-07-28 11:04 | lethosor | Description Updated | |
2017-07-28 11:04 | lethosor | Description Updated | |
2017-07-28 11:06 | lethosor | Description Updated | |
2017-07-28 11:06 | lethosor | Description Updated | |
2017-07-28 11:09 | lethosor | Note Added: 0036677 | |
2017-07-28 11:10 | lethosor | Summary | libgraphics.so incorrectly dlopens libncursesw.so.5, even though it needs .so.6, resulting in a segfault with PRINT_MODE:TEXT => libgraphics.so dlopen()ing libncursesw.so.5 can segfault on some systems with PRINT_MODE:TEXT |
2017-07-28 11:10 | lethosor | Summary | libgraphics.so dlopen()ing libncursesw.so.5 can segfault on some systems with PRINT_MODE:TEXT => libgraphics.so dlopen()ing libncursesw.so.5 instead of .so.6 can segfault on some systems with PRINT_MODE:TEXT |