NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

segfault in libterminfo with ncurses with nethack



I'm trying to adapt the games/nethack packages and enable building it
with ncurses. NetBSD's own curses has some trouble putting the cursor
where nethack wants it, which makes it annoying to play.
So I'm trying ncurses.

However at startup it crashes in NetBSD's libterminfo. Here is a stack
trace:

GNU gdb (GDB) 8.3
...
(gdb) r
Starting program: /usr/pkg/bin/nethack-curses 

Program received signal SIGSEGV, Segmentation fault.
ti_getflag (term=<optimized out>, id=0x7043f1643ee0 <name> "RGB") at /usr/src/lib/libterminfo/ti.c:53
53                      if (ud->type == 'f' && strcmp(ud->id, id) == 0)
(gdb) bt full
#0  ti_getflag (term=<optimized out>, id=0x7043f1643ee0 <name> "RGB") at /usr/src/lib/libterminfo/ti.c:53
        ind = <optimized out>
        i = 0
        ud = 0x230600000001
        term = <optimized out>
        ind = <optimized out>
        i = <optimized out>
        id = <optimized out>
        ud = <optimized out>
        ind = <optimized out>
        i = <optimized out>
        ud = <optimized out>
#1  0x00007043f1617e06 in start_color_sp () from /usr/pkg/lib/libncurses.so.6
No symbol table info available.
#2  0x0000000043a0fa6a in curses_init_nhwindows (argcp=<optimized out>, argv=<optimized out>) at ../win/curses/cursmain.c:164
No locals.
#3  0x0000000043a1c006 in main (argc=<optimized out>, argv=<optimized out>) at ../sys/unix/unixmain.c:212
        fd = <optimized out>
        dir = <optimized out>
        exact_username = 0 '\000'
        resuming = 0 '\000'
        plsel_once = 0 '\000'

At this point, the pointer ud has a bogus value:

(gdb) list ti_getflag
35      #include <term_private.h>
36      #include <term.h>
37
38      int
39      ti_getflag(const TERMINAL *term, const char *id)
40      {
41              ssize_t ind;
42              size_t i;
43              TERMUSERDEF *ud;
44
45              _DIAGASSERT(term != NULL);
46              _DIAGASSERT(id != NULL);
47
48              ind = _ti_flagindex(id);
49              if (ind != -1)
50                      return term->flags[ind];
51              for (i = 0; i < term->_nuserdefs; i++) {
52                      ud = &term->_userdefs[i];
53                      if (ud->type == 'f' && strcmp(ud->id, id) == 0)
54                              return ud->flag;
55              }
56              return ABSENT_BOOLEAN;
57      }
(gdb) print ud
$1 = (TERMUSERDEF *) 0x230600000001
(gdb)

When stopping at the start of ti_getflag, we have these values:

Breakpoint 1, ti_getflag (term=0x751486898000, id=0x751486243ee0 <name> "RGB") at /usr/src/lib/libterminfo/ti.c:40
40      {
(gdb) print *term
$2 = {fildes = -2037878784, name = 0x751486887000 "xterm-256color|xterm with 256 colors", desc = 0x75148689b030 "", 
  flags = 0x751486893050 "\222", nums = 0x751486878000, strs = 0x7514868ae000, _area = 0x75148688e000 "F\342\212\206\024u", 
  _arealen = 565063079886894, _nuserdefs = 5111808, _userdefs = 0x230600000001, _ospeed = 3, 
  _buf = 0x800ff04200005cf <error: Cannot access memory at address 0x800ff04200005cf>, _buflen = 1808788999554340119, 
  _bufpos = 5629504082285329, _snums = {164926744204800, 4294976006, 2305848261958716160, 5089738243505924, 1087077324213066755, 
    164926745477121, 164926744204800, 128731017052224, 128731016884283, 65, 1, 1, 1, 0 <repeats 13 times>}, _alias = 0x0}

same in hex:

(gdb) print/x *term
$3 = {fildes = 0x86887000, name = 0x751486887000, desc = 0x75148689b030, flags = 0x751486893050, nums = 0x751486878000, strs = 0x7514868ae000, 
  _area = 0x75148688e000, _arealen = 0x201ec0027002e, _nuserdefs = 0x4e0000, _userdefs = 0x230600000001, _ospeed = 0x3, 
  _buf = 0x800ff04200005cf, _buflen = 0x191a1c0300121517, _bufpos = 0x1400010f161311, _snums = {0x960000009600, 0x100002206, 0x200004c700004b00, 
    0x1215170800ff04, 0xf161311191a1c03, 0x960000140001, 0x960000009600, 0x7514868b0040, 0x75148688703b, 0x41, 0x1, 0x1, 0x1, 
    0x0 <repeats 13 times>}, _alias = 0x0}


Could there be any initialization missing, or done twice, that would
cause this?

If I select a terminal without colour, such as TERM=vt300, then the code
doens't get here, and the game seems to play normally. So the corrupted
values and/or memory seems rather localized. The only difference for a
colour terminal is that the curses function start_color(); is called.
With NetBSD's curses this also doesn't crash.
To me that seems to speak against some memory corruption caused by
NetHack.

(gdb) list curses_init_nhwindows
149     void
150     curses_init_nhwindows(int *argcp UNUSED,
151                           char **argv UNUSED)
152     {
153     #ifdef PDCURSES
154         char window_title[BUFSZ];
155     #endif
156
157     #ifdef XCURSES
158         base_term = Xinitscr(*argcp, argv);
159     #else
160         base_term = initscr();
161     #endif
162     #ifdef TEXTCOLOR
163         if (has_colors()) {
164             start_color();		<-- calls this and crashes as above
165             curses_init_nhcolors();
166         } else {
167             iflags.use_color = FALSE;
168             set_option_mod_status("color", SET_IN_FILE);
169             iflags.wc2_guicolor = FALSE;
170             set_wc2_option_mod_status(WC2_GUICOLOR, SET_IN_FILE);
171         }

Any libterminfo experts? _nuserdefs and filedes look fishy at least...

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert                            <rhialto/at/falu.nl>
\X/ There is no AI. There is just someone else's work.           --I. Rose

Attachment: signature.asc
Description: PGP signature



Home | Main Index | Thread Index | Old Index