bug-ncurses
[Top][All Lists]
Advanced

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

Re: gpsmon crashes in ncurses code


From: Thomas Dickey
Subject: Re: gpsmon crashes in ncurses code
Date: Sat, 18 Apr 2020 16:22:29 -0400
User-agent: NeoMutt/20170113 (1.7.2)

On Fri, Apr 17, 2020 at 03:25:24PM +0200, SZIGETVÁRI János wrote:
> Hi Thomas,
> 
> Thanks for your suggestions! I have finally got around to try them.
> Please see my findings in-line:
> 
> Thomas Dickey <address@hidden> ezt írta (időpont: 2020. ápr. 14., K, 0:42):
> 
> > The automatically-printed values look reasonable,
> > but the problem happens with line->text.
> > Printing
> >         print *line
> >
> 
> (gdb) print *line
> $1 = {text = 0x0, firstchar = 0, lastchar = 27, oldindex = 0}
> (gdb) print line->text
> $2 = (chtype *) 0x0
> 
> might show something, e.g., a value for line->text
> > If
> >         print line->text[2]
> >
> 
> (gdb) print line->text[1]
> Cannot access memory at address 0x4
> (gdb) print line->text[2]
> Cannot access memory at address 0x8
> 
> gives an error, that's confirming valgrind's warning.
> >
> > If you get an error, then there's still the problem of finding
> > why the pointer's bad.  (If you aren't able to get an error,
> > valgrind's probably misleading you on the cause)
> >
> > Also,
> >         print *win
> >
> 
> (gdb) print *win
> $3 = {_cury = 2, _curx = 1, _maxy = 18, _maxx = 27, _begy = 1, _begx = 0,
> _flags = 33, _attrs = 2097152, _bkgd = 32, _notimeout = false, _clear =
> false, _leaveok = false, _scroll = false, _idlok = false, _idcok = true,
> _immed = false,  _sync = true, _use_keypad = false, _delay = -1, _line =

What I can see looks normal, but the problem is the "text" pointer,
which is null.

_line is a pointer to an array of line data
(which is where "line" comes from, above):

(curses.h):

        struct ldat *_line;     /* the actual line data */

(curses.priv.h):
struct ldat
{
        NCURSES_CH_T    *text;          /* text of the line */
        NCURSES_SIZE_T  firstchar;      /* first changed character in the line 
*/
        NCURSES_SIZE_T  lastchar;       /* last changed character in the line */
        NCURSES_SIZE_T  oldindex;       /* index of the line at last update */
};

In gdb, you should be able to do

        print win->_line[0]
        print win->_line[1]
        print win->_line[2]     <---- the one that's bad
        print win->_line[3]

Perhaps the whole array has some problem.  I'd look at that first,
and try to see if it was actually initialized.

_line is allocated in newwin

    if ((win->_line = typeCalloc(struct ldat, ((unsigned) num_lines))) == 0) {

...and if you configured using "--with-trace", you could turn on the
trace feature, e.g.,

        rm -f trace
        NCURSES_TRACE=0x220 gpsmon

and the resulting file should show the number of lines and columns for
each window.  Here's an example from one of ncurses' test-programs:

creating newscr
+ + + called {newwin(0x55951a9f4240, 40,80,0,0)
+ + + + called {_nc_makenew(0x55951a9f4240,40,80,0,0)
create :window 0x55951a9fe130
+ + + + return }0x55951a9fe130
+ + + return }0x55951a9fe130
creating curscr
+ + + called {newwin(0x55951a9f4240, 40,80,0,0)
+ + + + called {_nc_makenew(0x55951a9f4240,40,80,0,0)
create :window 0x55951aa14570
+ + + + return }0x55951aa14570
+ + + return }0x55951aa14570
creating stdscr
+ + + called {newwin(0x55951a9f4240, 40,80,0,0)
+ + + + called {_nc_makenew(0x55951a9f4240,40,80,0,0)
create :window 0x55951aa2a9b0
+ + + + return }0x55951aa2a9b0
+ + + return }0x55951aa2a9b0
+ + return }0

Those (newscr, curscr, stdscr) are always created, but gpsmon
creates additional windows.  The tracemunch script can filter
a trace file so that the window-pointers are easier to read.

The _nc_makenew is done with this:

    T((T_CALLED("_nc_makenew(%p,%d,%d,%d,%d)"),
       (void *) SP_PARM, num_lines, num_columns, begy, begx));

with "tracemunch <trace", that's a little easier on the eyes:

creating newscr
+ + + called {newwin(screen1, 40,80,0,0)
+ + + + called {_nc_makenew(screen1,40,80,0,0)
create :window newscr
+ + + + return }newscr
+ + + return }newscr
creating curscr
+ + + called {newwin(screen1, 40,80,0,0)
+ + + + called {_nc_makenew(screen1,40,80,0,0)
create :window curscr
+ + + + return }curscr
+ + + return }curscr
creating stdscr
+ + + called {newwin(screen1, 40,80,0,0)
+ + + + called {_nc_makenew(screen1,40,80,0,0)
create :window stdscr
+ + + + return }stdscr
+ + + return }stdscr

Also, in the trace, each function that returns a value shows up
on the "return" lines.  Something might have failed, and not be
noticed -- the trace makes it easier to see than in gdb.

The "{" and "}" are there to help vi find the matching call/return lines.

> 0x153378, _regtop = 0, _regbottom = 18, _parx = 0, _pary = 0, _parent =
> 0x1511d0, _pad = {_pad_y = -1, _pad_x = -1, _pad_top = -1, _pad_left = -1,
> _pad_bottom = -1, _pad_right = -1}, _yoffset = 0}
> 
> 
> > might show something (see the lib_addch.c source -- negative values
> > for _cury and/or _curx would be bad, since "line" is updated at line 348).
> >
> > Seeing this on line 256:
> >     line = win->_line + y;
> >
> > then
> >         print win->_line + y
> >
> > should match "line".
> >
> 
> (gdb) print win->_line + y
> $4 = (struct ldat *) 0x153390
> (gdb) print line
> $5 = (struct ldat *) 0x153390
> (gdb)
> 
> 
> > However, the debugger says that x and y are both 2,
> > which is legal for the size of the window that's supposedly in use.
> >
> 
> So it seems that for some reason line->text is empty string, and there is

line->text is a null pointer (not the same as an empty string)

> only the null character and nothing else beyond that.
> The line pointer itself seems to point to the right place, at least as far
> as line and win->_line+y go.

-- 
Thomas E. Dickey <address@hidden>
https://invisible-island.net
ftp://ftp.invisible-island.net

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]