Subject: Re: bug#71274: 30.0.50; assertion failed: w->window_end_valid, in find_first_unchanged_at_end_row

From: Daniel Clemente <[email-masked]>
Date: Fri, 31 May 2024 10:08:18 +0000

> However, find_first_unchanged_at_end_row is called from try_window_id:
> > #3  0x00005555555de527 in try_window_id (w=0x5555622c4f68) at xdisp.c:22347
> And that function already checked that w->window_end_valid is
> non-zero, several dozens of lines before that:
>     /* Verify that display wasn't paused.  */
>     if (!w->window_end_valid)
>       GIVE_UP (8);

Between this check (the one "several dozens of lines before that"),
and the call to find_first_unchanged_at_end_row, something has the
side effect of changing window_end_valid to false. In particular:

  if (last_unchanged_at_beg_row)
    {
      /* Avoid starting to display in the middle of a character, a TAB
     for instance.  This is easier than to set up the iterator
     exactly, and it's not a frequent case, so the additional
     effort wouldn't really pay off.  */
      while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
          || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
         && last_unchanged_at_beg_row > w->current_matrix->rows)
    --last_unchanged_at_beg_row;

      if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
    GIVE_UP (17);

      if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
    GIVE_UP (18);

Before that last init_to_row_end, w->window_end_valid was true, and,
after it, it was false.
I saw it through fprintfs added before and after the line.
It's not always like that; sometimes it just stays true all through. I
still don't know the conditions to reproduce this, but I have seen
this bug 4 or 5 times yesterday+today.

So it must be a side effect of init_to_row_end.

I didn't have to read its code yet.

By the way, could this comment in try_window_id explain what is
happening? Maybe this part needs to be moved earlier.

  /* The redisplay iterations in display_line above could have
     triggered font-lock, which could have done something that
     invalidates IT->w window's end-point information, on which we
     rely below.  E.g., one package, which will remain unnamed, used
     to install a font-lock-fontify-region-function that called
     bury-buffer, whose side effect is to switch the buffer displayed
     by IT->w, and that predictably resets IT->w's window_end_valid
     flag, which we already tested at the entry to this function.
     Amply punish such packages/modes by giving up on this
     optimization in those cases.  */
  if (!w->window_end_valid)
    {
      clear_glyph_matrix (w->desired_matrix);
      return -1;
    }