Subject: Re: bug#77985: 31.0.50; infinite loop in `make-frame-names-alist`

From: martin rudalics <[email-masked]>
Date: Sat, 26 Apr 2025 20:51:42 +0200

> What about detecting when we made a full circle through all the
 > candidate frames, and stopping at that point?  Is that feasible?

Hard to tell.  next_frame itself already fails to do that.

   while (passed < 2)
     FOR_EACH_FRAME (tail, f)
       {
	if (passed)
	  {
	    f = candidate_frame (f, frame, minibuf);
	    if (!NILP (f))
	      return f;
	  }
	if (EQ (frame, f))
	  passed++;
       }
   return frame;

If candidate_frame returns nil for FRAME, f is never set to FRAME and
passed is never incremented.  This could be fixed as

--- a/src/frame.c
+++ b/src/frame.c
@@ -2205,7 +2205,7 @@ candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf)
  static Lisp_Object
  next_frame (Lisp_Object frame, Lisp_Object minibuf)
  {
-  Lisp_Object f, tail;
+  Lisp_Object f, f1, tail;
    int passed = 0;

    eassume (CONSP (Vframe_list));
@@ -2215,9 +2215,9 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
        {
  	if (passed)
  	  {
-	    f = candidate_frame (f, frame, minibuf);
-	    if (!NILP (f))
-	      return f;
+	    f1 = candidate_frame (f, frame, minibuf);
+	    if (!NILP (f1))
+	      return f1;
  	  }
  	if (EQ (frame, f))
  	  passed++;

But 'make-frame-names-alist', since it never sees frame set to
current-frame here,

     (while (not (eq frame current-frame))
       (progn
	(push (cons (frame-parameter frame 'name) frame) falist)
	(setq frame (next-frame frame 0))))

endlessly pushes the other frame to falist.

martin