Subject: bug#30322: Emacs 26 seems to have entered an infinite loop during GC on macOS

From: John Wiegley <[email-masked]>
Date: Thu, 01 Feb 2018 12:09:59 -0800

Hi Eli,

I was writing an e-mail to a colleague today when my Emacs window completely froze up, taking 100% CPU constantly.  Since it's still in that state now, I decided to fire up the stochastic profiler to see what it's doing.  I've attached the screenshot.

It claims to be spending all its time in `lisp_align_free', behaving as if there's a CPU busy loop now taking place inside that function. Since very little time is being assigned to its callees, I believe an infinite loop has occurred here:

      int i = 0;
      bool aligned = busy;
      struct ablock **tem = &free_ablock;
      struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1];

      while (*tem)
	{
	  if (*tem >= (struct ablock *) abase && *tem < atop)
	    {
	      i++;
	      *tem = (*tem)->x.next_free;
	    }
	  else
	    tem = &(*tem)->x.next_free;
	}

I would like to suggest that before entering this loop, we record the initial value of *tem, and if we encounter again (or if we encounter it again X number of times), we report a non-fatal error and exit this function.  That way I could save my work and restart Emacs.

I've noticed such a "lock up until I force quit" happening before, but it's very rare. Maybe a few times a year?

John