Subject: Re: bug#13007: 24.3.50; emacs_backtrace.txt

From: Dmitry Antipov <[email-masked]>
Date: Wed, 28 Nov 2012 11:19:29 +0400

IIUC crash is triggered by this fragment:

  13212    else if (EQ (selected_window, minibuf_window)
  13213             && (current_buffer->clip_changed || window_outdated (w))
  13214             && resize_mini_window (w, 0))

So selected_window is the same as minibuf_window, and w->buffer is not the
same as current_buffer; but, is w equal to XWINDOW (selected_window) here?

Look above:

  13114    /* Notice any pending interrupt request to change frame size.  */
  13115    do_pending_window_change (1);
  13116
  13117    /* do_pending_window_change could change the selected_window due to
  13118       frame resizing which makes the selected window too small.  */
  13119    if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
  13120      {
  13121        sw = w;
  13122        reconsider_clip_changes (w, current_buffer);
  13123      }
  13124
  13125    /* Clear frames marked as garbaged.  */
  13126    clear_garbaged_frames ();
  13127
  13128    /* Build menubar and tool-bar items.  */
  13129    if (NILP (Vmemory_full))
  13130      prepare_menu_bars ();

Here prepare_menu_bars can run Lisp and so change something.

  13131
  13132    if (windows_or_buffers_changed)
  13133      update_mode_lines++;
  13134
  13135    /* Detect case that we need to write or remove a star in the mode line.  */
  13136    if ((SAVE_MODIFF < MODIFF) != w->last_had_star)

If we ran Lisp above, how we can be sure that w is still equal to XWINDOW (selected_window)?

Can someone try this patch?

Dmitry
=== modified file 'src/xdisp.c'
--- src/xdisp.c	2012-11-27 03:10:32 +0000
+++ src/xdisp.c	2012-11-28 07:13:04 +0000
@@ -10903,6 +10903,9 @@
 static int
 window_outdated (struct window *w)
 {
+  if (w->pseudo_window_p)
+    /* Always update menu bar windows.  */
+    return 1;
   eassert (XBUFFER (w->buffer) == current_buffer);
   return (w->last_modified < MODIFF 
 	  || w->last_overlay_modified < OVERLAY_MODIFF);
@@ -13114,14 +13117,6 @@
   /* Notice any pending interrupt request to change frame size.  */
   do_pending_window_change (1);
 
-  /* do_pending_window_change could change the selected_window due to
-     frame resizing which makes the selected window too small.  */
-  if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
-    {
-      sw = w;
-      reconsider_clip_changes (w, current_buffer);
-    }
-
   /* Clear frames marked as garbaged.  */
   clear_garbaged_frames ();
 
@@ -13129,6 +13124,15 @@
   if (NILP (Vmemory_full))
     prepare_menu_bars ();
 
+  /* Resync because prepare_menu_bars may run Lisp or do_pending_window_change
+     could change the selected_window due to frame resizing which makes the
+     selected window too small.  */
+  if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
+    {
+      sw = w;
+      reconsider_clip_changes (w, current_buffer);
+    }
+
   if (windows_or_buffers_changed)
     update_mode_lines++;