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

From: Michael Welsh Duggan <[email-masked]>
Date: Mon, 05 Apr 2021 15:57:06 -0400

martin rudalics <[email-masked]> writes:

>  > buffer_window_count of the *Server* buffer was 1.  There were three
>  > frames that we looped over in the FOR_EACH_FRAME() loop.  Of these, only
>  > the first is interesting.  In this case window_list_1() in window_loop()
>  > returned three windows.  For each window, in the
>  > REPLACE_BUFFER_IN_WINDOWS_SAFELY case branch, EQ (w->contents, obj)
>  > returned false.  As a result, best_window is Qnil at the end, and
>  > replace-buffer_in_windows_safely_count never gets incremented.  For the
>  > other two frames the return value of window_list_1() was Qnil.
>
> Astonishing.  What are the names of these three buffers via
>
> p XBUFFER (w->contents)->name_
>
> Do they tell you anything about the Gnus configuration you wanted to
> quit?  I wouldn't be surprised if one of these were a dead buffer.

Surprisingly, no.  Three frames were checked.  The only buffers in
windows involved in the entire process were:

"build.ninja"  - I had that file in another frame
" *Minibuf-0*" - Looks like this was in the same frame as build.ninja?
"*Server*"     - This was the window whose buffer is being deleted
"*scratch*"    - The only window in the third frame

I trace through everything in detail here.  Maybe too much detail.
Maybe not enough.  Hopefully you can follow this session by following
the line numbers (mostly in window.c) and see what is going on.  The gdb
session, of course, still exists, and I now know I can recursively "call
replace-buffer_in_windows_safely(XIL(0x5555573fd885))" to trace through
it again, if you need me to.

(gdb) s
3443          if (buffer_window_count (XBUFFER (buffer)))
(gdb) n
3450              FOR_EACH_FRAME (tail, frame)
(gdb) n
3451                window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, true, frame);
(gdb) s
window_loop (type=REPLACE_BUFFER_IN_WINDOWS_SAFELY, obj=XIL(0x5555573fd885), 
    mini=true, frames=XIL(0x55555820ef55)) at ../../master/src/window.c:2967
2967      bool frame_best_window_flag = false;
(gdb) n
2973      if (FRAMEP (frames))
(gdb) 
2974        f = XFRAME (frames);
(gdb) 
2980      if (f)
(gdb) 
2981        frame_arg = Qlambda;
(gdb) 
2994      if (WINDOWP (obj))
(gdb) n
2996      else if (f)
(gdb) n
2997        window = FRAME_SELECTED_WINDOW (f);
(gdb) n
3001      windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
(gdb) n
3002      best_window = Qnil;
(gdb) p windows
$52 = XIL(0x555558be6443)
(gdb) ptype
type = union Lisp_X {
    <incomplete type>
} *
(gdb) n
3004      for (; CONSP (windows); windows = XCDR (windows))
(gdb) n
3008          window = XCAR (windows);
(gdb) n
3009          w = XWINDOW (window);
(gdb) n
3014          if (!MINI_WINDOW_P (w)
(gdb) p w->contents
$53 = XIL(0x5555578be555)
(gdb) xbuffer
$54 = (struct buffer *) 0x5555578be550
0x555557241db0 "build.ninja"
(gdb) n
3046                if (EQ (w->contents, obj))
(gdb) p obj
$55 = XIL(0x5555573fd885)
(gdb) xbuffer
$56 = (struct buffer *) 0x5555573fd880
0x5555571c18a0 "*Server*"
(gdb) n
3063                break;
(gdb) n
3004      for (; CONSP (windows); windows = XCDR (windows))
(gdb) n
3008          window = XCAR (windows);
(gdb) n
3009          w = XWINDOW (window);
(gdb) n
3014          if (!MINI_WINDOW_P (w)
(gdb) p w->contents
$57 = XIL(0x7ffff2a3cb15)
(gdb) xbuffer
$58 = (struct buffer *) 0x7ffff2a3cb10
0x7ffff2d244ea " *Minibuf-0*"
(gdb) n
3017              || type == REPLACE_BUFFER_IN_WINDOWS_SAFELY
(gdb) 
3046                if (EQ (w->contents, obj))
(gdb) 
3063                break;
(gdb) 
3004      for (; CONSP (windows); windows = XCDR (windows))
(gdb) 
3097      return best_window;
(gdb) 
3098    }
(gdb) 
replace_buffer_in_windows_safely (buffer=XIL(0x5555573fd885))
    at ../../master/src/window.c:3450
3450              FOR_EACH_FRAME (tail, frame)
(gdb) 
3451                window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, true, frame);
(gdb) s
window_loop (type=REPLACE_BUFFER_IN_WINDOWS_SAFELY, obj=XIL(0x5555573fd885), 
    mini=true, frames=XIL(0x555556fa294d)) at ../../master/src/window.c:2967
2967      bool frame_best_window_flag = false;
(gdb) n
2973      if (FRAMEP (frames))
(gdb) 
2974        f = XFRAME (frames);
(gdb) 
2980      if (f)
(gdb) 
2981        frame_arg = Qlambda;
(gdb) 
2994      if (WINDOWP (obj))
(gdb) 
2996      else if (f)
(gdb) 
2997        window = FRAME_SELECTED_WINDOW (f);
(gdb) 
3001      windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
(gdb) p window
$59 = XIL(0x55555734b355)
(gdb) xwindow
$60 = (struct window *) 0x55555734b350
84x59+0+0
(gdb) p $60->contents
$61 = XIL(0x5555573fd885)
(gdb) xbuffer
$62 = (struct buffer *) 0x5555573fd880
0x5555571c18a0 "*Server*"
(gdb) s
builtin_lisp_symbol (index=1) at ../../master/src/lisp.h:1007
1007      return make_lisp_symbol (&lispsym[index]);
(gdb) n
1008    }
(gdb) s
window_list_1 (window=XIL(0x55555734b355), minibuf=XIL(0x30), 
    all_frames=XIL(0xc0)) at ../../master/src/window.c:2863
2863      decode_next_window_args (&window, &minibuf, &all_frames);
(gdb) s
decode_next_window_args (window=0x7fffffffc858, minibuf=0x7fffffffc850, 
    all_frames=0x7fffffffc848) at ../../master/src/window.c:2672
2672      struct window *w = decode_live_window (*window);
(gdb) s
decode_live_window (window=XIL(0x55555734b355))
    at ../../master/src/window.c:246
246       if (NILP (window))
(gdb) n
249       CHECK_LIVE_WINDOW (window);
(gdb) n
250       return XWINDOW (window);
(gdb) n
251     }
(gdb) n
decode_next_window_args (window=0x7fffffffc858, minibuf=0x7fffffffc850, 
    all_frames=0x7fffffffc848) at ../../master/src/window.c:2673
2673      Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window;
(gdb) p w->contents
$63 = XIL(0x5555573fd885)
(gdb) xbuffer
$64 = (struct buffer *) 0x5555573fd880
0x5555571c18a0 "*Server*"
(gdb) n
2675      XSETWINDOW (*window, w);
(gdb) n
2678      if (NILP (*minibuf))
(gdb) n
2682      else if (!EQ (*minibuf, Qt))
(gdb) n
2690      if (NILP (*all_frames))
(gdb) n
2695      else if (EQ (*all_frames, Qvisible))
(gdb) n
2697      else if (EQ (*all_frames, make_fixnum (0)))
(gdb) n
2699      else if (FRAMEP (*all_frames))
(gdb) n
2701      else if (!EQ (*all_frames, Qt))
(gdb) n
2702        *all_frames = Qnil;
(gdb) n
2703    }
(gdb) n
window_list_1 (window=XIL(0x55555734b355), minibuf=XIL(0x30), 
    all_frames=XIL(0)) at ../../master/src/window.c:2864
2864      list = Qnil;
(gdb) n
2866      for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
(gdb) s
window_list () at ../../master/src/window.c:2563
2563      if (!CONSP (Vwindow_list))
(gdb) n
2581      return Vwindow_list;
(gdb) p Vwindow_list
$65 = XIL(0x555558bc6353)
(gdb) ptype
type = union Lisp_X {
    <incomplete type>
} *
(gdb) xcons
$66 = (struct Lisp_Cons *) 0x555558bc6350
{
  u = {
    s = {
      car = XIL(0x5555571ebfc5),
      u = {
        cdr = XIL(0x555558bc6363),
        chain = 0x555558bc6363
      }
    },
    gcaligned = 0xc5
  }
}
(gdb) n
2582    }
(gdb) n
window_list_1 (window=XIL(0x55555734b355), minibuf=XIL(0x30), 
    all_frames=XIL(0)) at ../../master/src/window.c:2867
2867        if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
(gdb) s
candidate_window_p (window=XIL(0x5555571ebfc5), owindow=XIL(0x55555734b355), 
    minibuf=XIL(0x30), all_frames=XIL(0)) at ../../master/src/window.c:2605
2605      struct window *w = XWINDOW (window);
(gdb) n
2606      struct frame *f = XFRAME (w->frame);
(gdb) p w->contents
$67 = XIL(0x5555578be555)
(gdb) xbuffer
$68 = (struct buffer *) 0x5555578be550
0x555557241db0 "build.ninja"
(gdb) n
2607      bool candidate_p = true;
(gdb) 
2609      if (!BUFFERP (w->contents))
(gdb) 
2611      else if (MINI_WINDOW_P (w)
(gdb) 
2619      else if (EQ (all_frames, Qt))
(gdb) 
2621      else if (NILP (all_frames))
(gdb) 
2623          eassert (WINDOWP (owindow));
(gdb) n
2624          candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
(gdb) n
2661      return candidate_p;
(gdb) p candidate_p
$69 = false
(gdb) n
2662    }
(gdb) n
window_list_1 (window=XIL(0x55555734b355), minibuf=XIL(0x30), 
    all_frames=XIL(0)) at ../../master/src/window.c:2866
2866      for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
(gdb) n
2867        if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
(gdb) s
candidate_window_p (window=XIL(0x55555820f3cd), owindow=XIL(0x55555734b355), 
    minibuf=XIL(0x30), all_frames=XIL(0)) at ../../master/src/window.c:2605
2605      struct window *w = XWINDOW (window);
(gdb) n
2606      struct frame *f = XFRAME (w->frame);
(gdb) p w->contents
$70 = XIL(0x7ffff2a3cb15)
(gdb) xbuffer
$71 = (struct buffer *) 0x7ffff2a3cb10
0x7ffff2d244ea " *Minibuf-0*"
(gdb) n
2607      bool candidate_p = true;
(gdb) n
2609      if (!BUFFERP (w->contents))
(gdb) n
2611      else if (MINI_WINDOW_P (w)
(gdb) n
2612               && (EQ (minibuf, Qlambda)
(gdb) n
2613                   || (WINDOWP (minibuf) && !EQ (minibuf, window))))
(gdb) n
2619      else if (EQ (all_frames, Qt))
(gdb) n
2621      else if (NILP (all_frames))
(gdb) n
2623          eassert (WINDOWP (owindow));
(gdb) n
2624          candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
(gdb) n
2661      return candidate_p;
(gdb) p candidate_p
$72 = false
(gdb) n
2662    }
(gdb) 
window_list_1 (window=XIL(0x55555734b355), minibuf=XIL(0x30), 
    all_frames=XIL(0)) at ../../master/src/window.c:2866
2866      for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
(gdb) 
2871      list = Fnreverse (list);
(gdb) n
2872      rest = Fmemq (window, list);
(gdb) p list
$73 = XIL(0)
(gdb) n
2873      if (!NILP (rest) && !EQ (rest, list))
(gdb) p rest
$74 = XIL(0)
(gdb) n
2880      return list;
(gdb) n
2881    }
(gdb) n
window_loop (type=REPLACE_BUFFER_IN_WINDOWS_SAFELY, obj=XIL(0x5555573fd885), 
    mini=true, frames=XIL(0x555556fa294d)) at ../../master/src/window.c:3002
3002      best_window = Qnil;
(gdb) p windows
$75 = XIL(0)
(gdb) p window
$76 = XIL(0x55555734b355)
(gdb) xwindow
$77 = (struct window *) 0x55555734b350
84x59+0+0
(gdb) p $77->contents
$78 = XIL(0x5555573fd885)
(gdb) xbuffer
$79 = (struct buffer *) 0x5555573fd880
0x5555571c18a0 "*Server*"
(gdb) n
3004      for (; CONSP (windows); windows = XCDR (windows))
(gdb) 
3097      return best_window;
(gdb) 
3098    }
(gdb) 
replace_buffer_in_windows_safely (buffer=XIL(0x5555573fd885))
    at ../../master/src/window.c:3450
3450              FOR_EACH_FRAME (tail, frame)
(gdb) 
3451                window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, true, frame);
(gdb) s
window_loop (type=REPLACE_BUFFER_IN_WINDOWS_SAFELY, obj=XIL(0x5555573fd885), 
    mini=true, frames=XIL(0x555555eff9dd)) at ../../master/src/window.c:2967
2967      bool frame_best_window_flag = false;
(gdb) n
2973      if (FRAMEP (frames))
(gdb) 
2974        f = XFRAME (frames);
(gdb) 
2980      if (f)
(gdb) 
2981        frame_arg = Qlambda;
(gdb) 
2994      if (WINDOWP (obj))
(gdb) 
2996      else if (f)
(gdb) 
2997        window = FRAME_SELECTED_WINDOW (f);
(gdb) 
3001      windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
(gdb) p window
$80 = XIL(0x555555effc45)
(gdb) xwindow
$81 = (struct window *) 0x555555effc40
80x23+0+1
(gdb) p $81->contents
$82 = XIL(0x7ffff256f6fd)
(gdb) xbuffer
$83 = (struct buffer *) 0x7ffff256f6f8
0x7ffff2d2003a "*scratch*"
(gdb) s
builtin_lisp_symbol (index=1) at ../../master/src/lisp.h:1007
1007      return make_lisp_symbol (&lispsym[index]);
(gdb) n
1008    }
(gdb) s
window_list_1 (window=XIL(0x555555effc45), minibuf=XIL(0x30), 
    all_frames=XIL(0xc0)) at ../../master/src/window.c:2863
2863      decode_next_window_args (&window, &minibuf, &all_frames);
(gdb) n
2864      list = Qnil;
(gdb) 
2866      for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
(gdb) 
2867        if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
(gdb) s
candidate_window_p (window=XIL(0x5555571ebfc5), owindow=XIL(0x555555effc45), 
    minibuf=XIL(0x30), all_frames=XIL(0)) at ../../master/src/window.c:2605
2605      struct window *w = XWINDOW (window);
(gdb) n
2606      struct frame *f = XFRAME (w->frame);
(gdb) p w->contents
$87 = XIL(0x5555578be555)
(gdb) xbuffer
$88 = (struct buffer *) 0x5555578be550
0x555557241db0 "build.ninja"
(gdb) n
2607      bool candidate_p = true;
(gdb) n
2609      if (!BUFFERP (w->contents))
(gdb) n
2611      else if (MINI_WINDOW_P (w)
(gdb) n
2619      else if (EQ (all_frames, Qt))
(gdb) n
2621      else if (NILP (all_frames))
(gdb) n
2623          eassert (WINDOWP (owindow));
(gdb) n
2624          candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
(gdb) n
2661      return candidate_p;
(gdb) p candidate_p
$89 = false
(gdb) n
2662    }
(gdb) n
window_list_1 (window=XIL(0x555555effc45), minibuf=XIL(0x30), 
    all_frames=XIL(0)) at ../../master/src/window.c:2866
2866      for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
(gdb) n
2867        if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
(gdb) s
candidate_window_p (window=XIL(0x55555820f3cd), owindow=XIL(0x555555effc45), 
    minibuf=XIL(0x30), all_frames=XIL(0)) at ../../master/src/window.c:2605
2605      struct window *w = XWINDOW (window);
(gdb) n
2606      struct frame *f = XFRAME (w->frame);
(gdb) p w->contents
$90 = XIL(0x7ffff2a3cb15)
(gdb) xbuffer
$91 = (struct buffer *) 0x7ffff2a3cb10
0x7ffff2d244ea " *Minibuf-0*"
(gdb) n
2607      bool candidate_p = true;
(gdb) n
2609      if (!BUFFERP (w->contents))
(gdb) n
2611      else if (MINI_WINDOW_P (w)
(gdb) n
2612               && (EQ (minibuf, Qlambda)
(gdb) n
2613                   || (WINDOWP (minibuf) && !EQ (minibuf, window))))
(gdb) n
2619      else if (EQ (all_frames, Qt))
(gdb) n
2621      else if (NILP (all_frames))
(gdb) n
2623          eassert (WINDOWP (owindow));
(gdb) n
2624          candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
(gdb) n
2661      return candidate_p;
(gdb) p candidate_p
$92 = false
(gdb) n
2662    }
(gdb) n
window_list_1 (window=XIL(0x555555effc45), minibuf=XIL(0x30), 
    all_frames=XIL(0)) at ../../master/src/window.c:2866
2866      for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
(gdb) n
2871      list = Fnreverse (list);
(gdb) n
2872      rest = Fmemq (window, list);
(gdb) n
2873      if (!NILP (rest) && !EQ (rest, list))
(gdb) n
2880      return list;
(gdb) p list
$93 = XIL(0)
(gdb) n
2881    }
(gdb) n
window_loop (type=REPLACE_BUFFER_IN_WINDOWS_SAFELY, obj=XIL(0x5555573fd885), 
    mini=true, frames=XIL(0x555555eff9dd)) at ../../master/src/window.c:3002
3002      best_window = Qnil;
(gdb) n
3004      for (; CONSP (windows); windows = XCDR (windows))
(gdb) n
3097      return best_window;
(gdb) n
3098    }
(gdb) n
replace_buffer_in_windows_safely (buffer=XIL(0x5555573fd885))
    at ../../master/src/window.c:3450
3450              FOR_EACH_FRAME (tail, frame)
(gdb) n
3454          eassert (count == replace_buffer_in_windows_safely_count);
(gdb) p count
$94 = 1
(gdb) p replace_buffer_in_windows_safely_count 
$95 = 0

-- 
Michael Welsh Duggan
([email-masked])