A couple of days ago, my XEmacs crashed when I did something as
innocent as narrowing-to-region and then M-<. I haven't seen this
before, but it turned out to be repeatable - but heavily dependent on
the exact file, region, font setup, etc, so I didn't reproduce it in a
vanilla standard XEmacs.
The crash was an assertion failure in the first check in
extents.c:extent_fragment_update()
Tracing back the reason for this, it was that
redisplay.c:start_with_line_at_pixpos()
was returning a value before the start of the narrowed region.
Of course, this is my heavily modified Unicode-internal fork of 21.4,
but as far as I can see, nothing I've done is implicated in the
problem.
One return point of start_with_line_at_pixpos()
is inside the while ( cur_elt < 0 ) { ... }
loop, and at the point it is checked whether cur_pos is before
BUF_BEGV before returning it.
There's another return point inside if (pixheight < 0) {...}
before that loop, in which either prev_pos or cur_pos is returned,
without checking whether they're less than BUF_BEGV. It may be that
prev_pos can't be, because it would have been caught by the other
check in the previous iteration of the main loop; but I can't see why
cur_pos might not be, as indeed it was in the crash I saw.
I added a check at that point, and the crash went away.
If this is a bug, rather than a subtle consequence of an assumption
being broken by some other bug I've introduced, it probably applies to
all current XEmacsen, as this code is still current in the latest 21.5.
However, my understanding of the redisplay code is, to put it
mildly, limited.
This is what I've done:
*** redisplay.c 2012/06/03 15:16:04 1.42
--- redisplay.c 2014/01/01 11:01:33 1.43
***************
*** 8181,8192 ****
if (pixheight < 0)
{
w->line_cache_validation_override--;
if (-pixheight > point_line_height)
/* We can't make the target line cover pixpos, so put it
above pixpos. That way it will at least be visible. */
! return prev_pos;
else
! return cur_pos;
}
cur_elt--;
--- 8181,8195 ----
if (pixheight < 0)
{
w->line_cache_validation_override--;
+ /* I see no reason why cur_pos can't be before BEGV
+ here, so check for it. It's not clear to me whether
+ prev_pos could be before BEGV, so check that as well. */
if (-pixheight > point_line_height)
/* We can't make the target line cover pixpos, so put it
above pixpos. That way it will at least be visible. */
! return (prev_pos <= BUF_BEGV (b)) ? BUF_BEGV (b) : prev_pos;
else
! return (cur_pos <= BUF_BEGV (b)) ? BUF_BEGV (b) : cur_pos;
}
cur_elt--;
_______________________________________________
XEmacs-Beta mailing list
XEmacs-Beta(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-beta