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

From: martin rudalics <[email-masked]>
Date: Tue, 30 Mar 2021 18:52:15 +0200

>> Are the buffer names the same as last time?
 >
 > Yes.

It all sounds so easily reproducible and I have no idea where to start.
Please bear with me and run with the attached from now on.

Thanks, martin
diff --git a/src/buffer.c b/src/buffer.c
index 8e33162989..9ad1e1d4d8 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1991,6 +1991,8 @@ DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
 
   run_buffer_list_update_hook (b);
 
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
   return Qt;
 }
 
@@ -2151,6 +2153,9 @@ set_buffer_internal_1 (register struct buffer *b)
 
   BUFFER_CHECK_INDIRECTION (b);
 
+  if (!BUFFER_LIVE_P (b))
+    error ("Selecting deleted buffer");
+
   old_buf = current_buffer;
   current_buffer = b;
   last_known_column_point = -1;   /* Invalidate indentation cache.  */
diff --git a/src/window.c b/src/window.c
index eb16e2a433..8cea0af8ab 100644
--- a/src/window.c
+++ b/src/window.c
@@ -307,7 +307,11 @@ wset_buffer (struct window *w, Lisp_Object val)
   if (BUFFERP (val))
     /* Make sure that we do not assign the buffer
        to an internal window.  */
-    eassert (MARKERP (w->start) && MARKERP (w->pointm));
+    {
+      eassert (BUFFER_LIVE_P (XBUFFER (val)));
+      eassert (MARKERP (w->start) && MARKERP (w->pointm));
+    }
+
   w->contents = val;
   adjust_window_count (w, 1);
 }
@@ -315,6 +319,7 @@ wset_buffer (struct window *w, Lisp_Object val)
 static void
 wset_old_buffer (struct window *w, Lisp_Object val)
 {
+  eassert (BUFFER_LIVE_P (XBUFFER (val)));
   w->old_buffer = val;
 }
 
@@ -594,6 +599,8 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
 
   selected_window = window;
 
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
   /* Go to the point recorded in the window.
      This is important when the buffer is in more
      than one window.  It also matters when
@@ -3411,6 +3418,8 @@ DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal,
 replace_buffer_in_windows (Lisp_Object buffer)
 {
   call1 (Qreplace_buffer_in_windows, buffer);
+
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
 }
 
 /* If BUFFER is shown in a window, safely replace it with some other
@@ -3960,6 +3969,8 @@ run_window_change_functions (void)
   /* Record changes for all frames (if asked for), selected window and
      frame.  */
   unbind_to (count, Qnil);
+
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
 }
 
 /* Make WINDOW display BUFFER.  RUN_HOOKS_P means it's allowed
@@ -4054,6 +4065,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
   if (!samebuf && !MINI_WINDOW_P (w) && !WINDOW_PSEUDO_P (w))
     FRAME_WINDOW_CHANGE (XFRAME (w->frame)) = true;
 
+  if (WINDOWP (selected_window))
+    eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
   unbind_to (count, Qnil);
 }
 
@@ -5174,6 +5188,8 @@ DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_interna
       error ("Deletion failed");
     }
 
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
   return Qnil;
 }
 
@@ -7233,6 +7249,9 @@ DEFUN ("set-window-configuration", Fset_window_configuration,
   minibuf_selected_window = data->minibuf_selected_window;
 
   SAFE_FREE ();
+
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
   return FRAME_LIVE_P (f) ? Qt : Qnil;
 }
 
diff --git a/src/xdisp.c b/src/xdisp.c
index cc0a689ba3..ea64e5037a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12980,6 +12980,8 @@ restore_selected_window (Lisp_Object window)
       /* Abort if we cannot find a live frame.  */
       emacs_abort ();
     }
+
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
 }
 
 /* Restore WINDOW, if live, as its frame's selected window.  */
@@ -12997,6 +12999,8 @@ restore_frame_selected_window (Lisp_Object window)
       if (EQ (frame, selected_frame))
 	selected_window = window;
     }
+
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
 }
 
 /* Update the tab-bar item list for frame F.  This has to be done
@@ -13074,6 +13078,8 @@ update_tab_bar (struct frame *f, bool save_match_data)
 	  XSETFRAME (frame, f);
 	  selected_frame = frame;
 	  selected_window = FRAME_SELECTED_WINDOW (f);
+
+	  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
 #endif
 
 	  /* Build desired tab-bar items from keymaps.  */
@@ -14010,6 +14016,8 @@ update_tool_bar (struct frame *f, bool save_match_data)
 	  selected_frame = frame;
 	  selected_window = FRAME_SELECTED_WINDOW (f);
 
+	  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
 	  /* Build desired tool-bar items from keymaps.  */
           new_tool_bar
 	    = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
@@ -17246,6 +17254,8 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
       set_buffer_internal (XBUFFER (w->contents));
     }
 
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
   return startp;
 }
 
@@ -25450,6 +25460,8 @@ display_mode_lines (struct window *w)
 
   unbind_to (count, Qnil);
 
+  eassert (BUFFER_LIVE_P (XBUFFER (XWINDOW (selected_window)->contents)));
+
   if (n > 0)
     w->must_be_updated_p = true;
   return n;