[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
signature.asc
Description: PGP signature