Subject: bug#7728: 24.0.50; GDB backtrace from abort

From: martin rudalics <[email-masked]>
Date: Wed, 12 Jan 2011 18:42:55 +0100

> Are you saying tha this isn't kosher, because the body of
 > save-window-excursion is not allowed to select a different frame?

I doubt it's kosher because if the old selected window is not on the
restored frame and a window on the restored frame gets selected, the
point of the buffer whose window is deselected is not stored in the old
selected window's pointm which is certainly not TRT.

Inherently, the source of all evil is the idea to have (1) these two
variables selected_frame and selected_window and (2) to allow setting
them independently from each other.

To avoid the present crash we could try something like the attached
patch (which does not try to solve anything but that crash).

martin
*** c:/window.c	2011-01-07 08:25:53.406250000 +0100
--- c:/window.c	2011-01-12 18:25:01.859375000 +0100
***************
*** 158,163 ****
--- 158,167 ----
  
  static int window_initialized;
  
+ /* ...  */
+ 
+ static int inhibit_point_swap;
+ 
  /* Hook to run when window config changes.  */
  
  static Lisp_Object Qwindow_configuration_change_hook;
***************
*** 3594,3600 ****
    /* Store the current buffer's actual point into the
       old selected window.  It belongs to that window,
       and when the window is not selected, must be in the window.  */
!   if (!NILP (selected_window))
      {
        ow = XWINDOW (selected_window);
        if (! NILP (ow->buffer))
--- 3598,3606 ----
    /* Store the current buffer's actual point into the
       old selected window.  It belongs to that window,
       and when the window is not selected, must be in the window.  */
!   if (inhibit_point_swap)
!     inhibit_point_swap = 0;
!   else
      {
        ow = XWINDOW (selected_window);
        if (! NILP (ow->buffer))
***************
*** 3602,3607 ****
--- 3608,3615 ----
  			 BUF_PT (XBUFFER (ow->buffer)),
  			 BUF_PT_BYTE (XBUFFER (ow->buffer)));
      }
+   else
+     inhibit_point_swap = 0;
  
    selected_window = window;
  
***************
*** 5767,5773 ****
      /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
         when passed below to set_marker_both.  */
      error ("move-to-window-line called from unrelated buffer");
!   
    window = selected_window;
    start = marker_position (w->start);
    if (start < BEGV || start > ZV)
--- 5775,5781 ----
      /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
         when passed below to set_marker_both.  */
      error ("move-to-window-line called from unrelated buffer");
! 
    window = selected_window;
    start = marker_position (w->start);
    if (start < BEGV || start > ZV)
***************
*** 6147,6153 ****
        /* Prevent "swapping out point" in the old selected window
  	 using the buffer that has been restored into it.
  	 We already swapped out point that from that window's old buffer.  */
!       selected_window = Qnil;
  
        /* Arrange *not* to restore point in the buffer that was
  	 current when the window configuration was saved.  */
--- 6155,6161 ----
        /* Prevent "swapping out point" in the old selected window
  	 using the buffer that has been restored into it.
  	 We already swapped out point that from that window's old buffer.  */
!       inhibit_point_swap = 1;
  
        /* Arrange *not* to restore point in the buffer that was
  	 current when the window configuration was saved.  */