Subject: Re: bug#78054: 31.0.50; igc: infinite recursion

From: Pip Cet <[email-masked]>
Date: Fri, 25 Apr 2025 01:07:20 +0000

Óscar Fuentes via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <[email-masked]> writes:

> Emacs froze just after pressing 'g' in a Magit status buffer (that key
> refreshes the displayed status of the git repo.)

Thanks!  I see two problems:

1. Emacs wasn't actually idle, but we called igc_on_idle.  We should
probably move that call to happen only when timer_idleness_start_time is
valid (or is there a better way to check whether we're idle?).

2. compact_buffer sets

      BUF_COMPACT (buffer) = BUF_MODIFF (buffer);

after it compacts the buffer, not before.  However, even setting it
before and after the actual compaction (which may call out to Lisp)
isn't sufficient.

3. I always thought that igc_on_idle remembered where it was in the
buffer alist across calls.  That appears to be incorrect, we just start
over from the beginning of the buffer list every time.

I think the unusual thing in your session was that the buffer which was
at the head of the alist produced an undo limit warning, and we always
start our idle work by compacting the first buffer in the list.

> Neither C-g nor SIGUSR2 had any effect.
>
> This is an excerpt of the backtrace, there are thousands of frames and
> apparently they show a recursive cycle.

I'm surprised you didn't see a stack overflow manifesting as a segfault,
but maybe that would have happened eventually.

> "sit-for" (0xa66ce438)
> "display-warning" (0xa66ce618)
> "undo-outer-limit-truncate" (0xa66ce698)
> "sit-for" (0xa66ce9e8)

Note that the call is (sit-for 0).  I don't think that should cause us
to do idle work.

Pip