Subject: Re: bug#47244: 28.0.50; SIGSEGV in long-runnning Emacs

From: martin rudalics <[email-masked]>
Date: Sat, 10 Apr 2021 09:15:53 +0200

> I've tried to recreate a problem with this patch and have successfully
 > failed.  I'll continue using it for a few days, and I will let you know
 > if I see any problems, but I think that protecting window_list() from
 > quit fixes the problem(s) I reported.

Your impatience revealed this bug and your patience located it.  I now
attach a clean patch which also protects the occurrence in window_list_1
although that one doesn't appear so vulnerable - likely because quitting
always eats the maybe_quit from window_list first.  If you don't see any
problems with it within a week or so, I'll install it.

martin
diff --git a/src/window.c b/src/window.c
index eb16e2a433..aa60624d63 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2556,8 +2556,10 @@ window_list (void)
   if (!CONSP (Vwindow_list))
     {
       Lisp_Object tail, frame;
+      ptrdiff_t count = SPECPDL_INDEX ();

       Vwindow_list = Qnil;
+      specbind (Qinhibit_quit, Qt);
       FOR_EACH_FRAME (tail, frame)
 	{
 	  Lisp_Object arglist = Qnil;
@@ -2569,6 +2571,8 @@ window_list (void)
 	  arglist = Fnreverse (arglist);
 	  Vwindow_list = nconc2 (Vwindow_list, arglist);
 	}
+
+      unbind_to (count, Qnil);
     }

   return Vwindow_list;
@@ -2865,11 +2869,16 @@ window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
   rest = Fmemq (window, list);
   if (!NILP (rest) && !EQ (rest, list))
     {
+      ptrdiff_t count = SPECPDL_INDEX ();
+
+      specbind (Qinhibit_quit, Qt);
       for (tail = list; !EQ (XCDR (tail), rest); tail = XCDR (tail))
 	;
       XSETCDR (tail, Qnil);
       list = nconc2 (rest, list);
+      unbind_to (count, Qnil);
     }
+
   return list;
 }