Follow-up Comment #2, bug #67589 (group screen):

I can reproduce this on GNU/Linux every time, on screen-v5 HEAD (bf51977) as
well as 5.0.2. The crash needs two displays attached to the session (screen
-x, or -xR as in the original report) and %+Lw in the hardstatus or caption.

Steps:

1. A screenrc with:

   hardstatus alwayslastline
   hardstatus string '%-Lw%n %t%+Lw'

2. screen -c that-screenrc -S t, then create a second window (C-a c) so that
windows 0 and 1 exist.
3. In a second terminal: screen -x t, and select window 1 there too.
4. Type exit in window 1. The whole session dies.

Backtrace (screen-v5 HEAD, -g -O2):


#6  AddWindows (flags=4) at process.c:6017          cur == NULL
#7  __WinMsgEscWinNames at winmsg.c:408
#8  MakeWinMsgEv at winmsg.c:786
#9  RefreshHStatus at display.c:1717
#10 WindowChanged at winmsg.c:955
#11 WindowChanged (what=WINESC_WFLAGS) at winmsg.c:916
#12 Activate at process.c:5853
#13 KillWindow at process.c:5957
#14 WindowDied at window.c:1958


AddressSanitizer reports the same thing: "SEGV on unknown address
0x000000000008" in AddWindows process.c:6017. The 0x8 in the macOS report
above is the same address: it is the offset of w_next in a NULL Window
pointer.

Cause: KillWindow() first unlinks the dying window from the window list, then
loops over the displays and switches each canvas that shows it. For each such
display it calls Activate(-1). Activate() calls WindowChanged(), which redraws
the hardstatus of all displays, not only the current one. A display that the
loop has not reached yet still has the dying window as D_fore, so AddWindows()
is called with that window's number. GetWindowByNumber() finds no window for
it any more and returns NULL, and the %+Lw case dereferences cur->w_next.

So it needs the dying window to be visible on two displays, and to be the
foreground window of the display that comes later in the displays list. That
is why it seems random, and why it does not reproduce with a single display.

The attached patch makes AddWindows() list nothing for %-Lw / %+Lw when the
reference window no longer exists. The Window itself is still allocated at
that point (FreeWindow() runs at the end of KillWindow()), and the stale
display is switched and redrawn a moment later in the same loop, so only that
intermediate frame is affected. Scripted, the steps above crash screen-v5 HEAD
5 out of 5 times. With the patch they survive 20 out of 20 runs on screen-v5
HEAD and on 5.0.2, plus 5 out of 5 on 5.0.2 under AddressSanitizer with no
report, and the session stays usable afterwards.

The same commit is also on GitHub, on top of screen-v5 bf51977:
https://github.com/congzhangzh/screen/commit/411da54 (branch
fix-addwindows-killed-window).

A deeper alternative would be to switch the canvases of all displays first and
call Activate() afterwards, so that no display keeps a D_fore that is no
longer in the window list. I kept the patch minimal; I am happy to rework it
that way if you prefer.

Bug #68648 ("Screen crashing, suspect Multi display mode") is probably the
same crash.

Unrelated, found while building screen-v5 HEAD with gcc 16: pty.c needs
<pty.h> for openpty() (Debian carries a patch for this), and window.c needs
_GNU_SOURCE for execvpe().


(file #59166)

    _______________________________________________________

Additional Item Attachment:

Fix: AddWindows() lists nothing for %-Lw/%+Lw when the reference window is
gone (against screen-v5 bf51977)

Name:
0001-Fix-crash-in-AddWindows-when-a-window-shown-on-two-displays-exits.patch
Size: 1.9KiB

<https://file.savannah.gnu.org/file/0001-Fix-crash-in-AddWindows-when-a-window-shown-on-two-displays-exits.patch?file_id=59166>


    AGPL NOTICE

These attachments are served by Savane. You can download the corresponding
source code of Savane at
https://savannah.gnu.org/source/savane-8c6c341578ed1ff525dc746b94af9a11d30d7444.tar.gz


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?67589>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/

Attachment: signature.asc
Description: PGP signature

Reply via email to