Subject: bug#39977: 28.0.50; Unhelpful stack trace

From: martin rudalics <[email-masked]>
Date: Tue, 17 Mar 2020 10:38:11 +0100

> Why does it matter which SELECTED_FRAME crashes?

Because the next crash may happen at some time in the future.  Why not
cure the first crash we have right away?

 > Anyway, my point was a different one: it was that we cannot simply
 > "not select" such a frame, we need to do something else.  What exactly
 > is not trivial, and I didn't understand what you were suggesting to
 > do.
 >
 >>   >> As far as frame.c is concerned, it should do something like in the
 >>   >> attached patch.
 >>   >
 >>   > We cannot punt like that in the display engine.
 >>
 >> Why not?
 >
 > Because we must have a frame that we were supposed to redisplay.

Either we are miscommunicating or I' m just dumb.  I would in no way
restrict the display engine in choosing whatever live frame it wants to
redisplay.

 > The display engine doesn't select frames to show them to the user, it
 > selects them to redraw their windows.  So the considerations what to
 > do in this case are different from those we need to consider when the
 > user selects a frame.

As I said above: This is not about the frame its windows it has to
redraw.  It's about the display engine trying to select a frame after
it has redrawn (parts of) another frame's windows.

 >> Not "will" but "may".  The problem is that it then might be harder
 >> to find the cause.
 >>
 >> With emacs -Q evaluate
 >>
 >> (defvar foo
 >>     '(:eval
 >>       (when (> (length (frame-list)) 1)
 >>         (delete-frame (next-frame)))))
 >>
 >> (setq-default mode-line-format foo)
 >>
 >> and do C-x 5 2.  The backtrace I get here is
 >
 > Which just means we need to add the protection to SELECTED_FRAME
 > itself, so that it runs everywhere.

But SELECTED_FRAME is not the cause of this problem.  The cause of the
problem is AFAICT the fact that :eval is allowed to do silly things
while the display engine tries to redraw windows.  The example above is
only a mirror of

----------------------
With emacs -Q evaluate

(defvar foo
   '(:eval
     (when (> (length (frame-list)) 1)
       (delete-frame))))

(setq-default mode-line-format foo)

and do C-x 5 2.
---------------

where I'm told that

:eval deleted the frame being displayed

So the display engine is, in principle, aware of one incarnation of the
problem - the one where an :eval tries to delete under its feet the
frame it currently tries to redraw and the comment correctly says that

   This is a nonsensical thing to do,
   and signaling an error from redisplay might be
   dangerous, but we cannot continue with an invalid frame.

So here the display engine bows out.  OTOH we allow it to set
selected_frame to an equally invalid frame.  Isn't that a bit selfish?

martin