Subject: bug#77065: 31.0.50; Infinite loop in move_it_to

From: Yifan Zhu <[email-masked]>
Date: Mon, 17 Mar 2025 07:58:41 -0700

Hi,

Thank you for your prompt response!

On 3/17/25 7:27 AM, Eli Zaretskii wrote:
> Thanks, but I don't have access to a system where these prerequisites
> can be met.  So either someone can reproduce this, debug the problem,
> and describe the reason for the loop, or I'd need to ask you to do it,
> if possible.  Or, if you can show a recipe for reproducing the problem
> without installing LaTeX and xenops, I could try reproducing this on
> the systems to which I have access.
I suspect that having (multiple) images inline might be the cause of the 
issue -- do you have any suggestions on how to recreate this in vanilla 
emacs?
> Can you describe how you arrived at the conclusion that it infloops in
> that function?
In gdb, I switched to that frame and typed finish, the process hangs. In 
any lower frame I can successfully finish.
> Can you step in GDB through one iteration of that
> loop and show the values of variables which cause Emacs never to exit
> the loop?

I am not sure which variables I should show, as I am having some trouble 
understanding the exit conditions of that infinite loop. Basically 
`move_it_in_display_line_to` always returns `MOVE_LINE_CONTINUED`, and 
below is one iteration of stepping through the loop:

10947          switch (skip)
10990          max_current_x = it->last_visible_x;
10995          if (it->c == '\t')
11030            it->continuation_lines_width += it->current_x;
11031          break;
11038          it->current_x = line_start_x;
11039          it->wrap_prefix_width = 0;
11040          line_start_x = 0;
11041          it->hpos = 0;
11042          it->line_number_produced_p = false;
11043          it->current_y += it->max_ascent + it->max_descent;
11044          ++it->vpos;
11045          last_height = it->max_ascent + it->max_descent;
11046          it->max_ascent = it->max_descent = 0;
10759          if (op & MOVE_TO_VPOS)
10803          else if (op & MOVE_TO_Y)
10932          else if (BUFFERP (it->object)
10933               && (it->method == GET_FROM_BUFFER
10934               || it->method == GET_FROM_STRETCH)
10945        skip = move_it_in_display_line_to (it, to_charpos, -1, 
MOVE_TO_POS);
10947          switch (skip)

>> #1  0x0000555555622e6c in move_it_to (it=0x7fffffff6df0, to_charpos=218,
>> to_x=-1, to_y=-1, to_vpos=-1, op=8) at xdisp.c:10945
> The downstream bug report shows a very different (much larger) buffer
> position as the value of to_charpos (34559).  Is that expected? is
> that significant?

Great catch -- the much larger buffer position might be because I was 
(incorrectly) working with a larger document. I would say that it is not 
significant, as I could reproduce the issue with a much smaller document.