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/
signature.asc
Description: PGP signature
