Subject: Re: bug#11984: 24.1; segfault while deleting a window

From: Chong Yidong <[email-masked]>
Date: Thu, 19 Jul 2012 11:39:47 +0800

Eli Zaretskii <[email-masked]> writes:

> Please see if this isn't a duplicate of #11677.

I think the fix for 11677 doesn't go far enough.  I can still produce a
crash on trunk by calling delete-other-windows-internal for a window on
a dead frame:

M-: (setq w (selected-window)) RET
M-: (setq f (selected-frame)) RET
C-x 5 2
M-: (delete-frame f) RET
M-: (delete-other-windows-internal w) RET
Fatal error (11)Segmentation fault (core dumped)

There's a similar problem with window-absolute-pixel-edges.

I committed a fix to the emacs-24 branch adding CHECK_LIVE_FRAME calls
to those two functions (patch below).  But for long-term safety, I think
decode_any_windows had better signal an error if the window's frame
isn't live.  But I'm not sure if there's any subtle reliance in existing
code on allowing window functions to be called for windows on dead
frames---anyone know?

*** src/ChangeLog	2012-07-14 10:46:56 +0000
--- src/ChangeLog	2012-07-19 03:33:08 +0000
***************
*** 1,3 ****
--- 1,9 ----
+ 2012-07-19  Chong Yidong  <[email-masked]>
+ 
+ 	* window.c (Fwindow_absolute_pixel_edges)
+ 	(Fdelete_other_windows_internal): Signal an error if the window is
+ 	on a dead frame (Bug#11984).
+ 
  2012-07-14  Eli Zaretskii  <[email-masked]>
  
  	Remove FILE_SYSTEM_CASE.

=== modified file 'src/window.c'
*** src/window.c	2012-04-23 16:22:23 +0000
--- src/window.c	2012-07-19 03:33:08 +0000
***************
*** 484,492 ****
    (Lisp_Object window, Lisp_Object limit)
  {
    register struct window *w = decode_any_window (window);
- 
    w->combination_limit = limit;
- 
    return w->combination_limit;
  }
  
--- 484,490 ----
***************
*** 800,805 ****
--- 798,805 ----
  {
    register struct window *w = decode_any_window (window);
    int add_x, add_y;
+ 
+   CHECK_LIVE_FRAME (w->frame);
    calc_absolute_offset (w, &add_x, &add_y);
  
    return Fcons (make_number (WINDOW_LEFT_EDGE_X (w) + add_x),
***************
*** 2568,2573 ****
--- 2568,2574 ----
    Mouse_HLInfo *hlinfo;
  
    w = decode_any_window (window);
+   CHECK_LIVE_FRAME (w->frame);
    XSETWINDOW (window, w);
    f = XFRAME (w->frame);
  
***************
*** 2581,2586 ****
--- 2582,2588 ----
      /* ROOT must be an ancestor of WINDOW.  */
      {
        r = decode_any_window (root);
+       CHECK_LIVE_FRAME (r->frame);
        pwindow = XWINDOW (window)->parent;
        while (!NILP (pwindow))
  	if (EQ (pwindow, root))