tiemann@mcc-pp.UUCP (Michael Tiemann) (09/19/86)
It appears that (struct windows) and (struct Lisp_Process)
are not allocated for properly.
Problem:
file: window.c
function: make_window
Lisp_Object
make_window ()
{
Lisp_Object val;
register struct window *p;
val = Fmake_vector (
make_number ((sizeof(struct window) - sizeof(struct Lisp_Vector))
/ sizeof(Lisp_Object)),
Qnil);
XSETTYPE (val, Lisp_Window);
/* ... code deleted ... */
return val;
}
The problem is that the definition of a Lisp_Vector is
struct Lisp_Vector
{
int size;
struct Lisp_Vector *next;
Lisp_Object contents[1];
};
and while the window declaration makes room for the first two fields
(size and next) it does not save room for contents! As a result,
with rcheck enabled, magic numbers for windows (like the minibuf_window)
will be overwritten in their last position.
The fix is to add ask for one more Lisp_Object, then when we subtract
sizeof(struct Lisp_Vector), that 1 offsets contents.
I looked around for other places that this might happen, and it happens
in process.c: function make_process.
Whoever wrote the code had the right idea, but got it backwards:
instead of adding 1 to offset contents, 1 was subtracted from the
request! This left the last TWO fields to clobber magic
numbers.
Also, in xdisp.c, function redisplay_window, if the function is
called with a dummy parent (like when splitting a window for the first time),
its w->start is not a valid argument to marker_position:
marker_position expects a marker, never Qnil. Rather then modify
marker_position, one can move the register initialization
{register int startp = marker_position (w->start);} from the
declaration section into the body of redisplay_window
(after the check {if (NULL (w->buffer)) abort();} (always a
good practice, I think). Then, the recursive call will do the child
and return, without ever calling marker_position (more efficient!).
When the stucture shapes are modified, the bugs are forced
out of their corners... For people interested in validating
GNU-emacs, try running it as distributed, then change
structure shapes that *should not* matter. You'll be amazed
at what shows up...
To the keeper of GNU: please let me know when(/if) these are
incorporated, thanks
Michael
tiemann@mcc.com