nvim --version:NVIM v0.4.0-430-g8698830cb
Build type: RelWithDebInfo
LuaJIT 2.0.5
Compilation: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe /DWIN32 /D_WINDOWS /W3 /MD /Zi /O2 /Ob1 /DNDEBUG -DMIN_LOG_LEVEL=3 /W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -D_WIN32_WINNT=0x0600 -DINCLUDE_GENERATED_DECLARATIONS -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -IC:/projects/neovim/build/config -IC:/projects/neovim/src -IC:/projects/neovim/.deps/usr/include -IC:/projects/neovim/build/src/nvim/auto -IC:/projects/neovim/build/include
Compiled by appveyor@APPVYR-WIN
Features: -acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM\sysinit.vim"
fall-back for $VIM: "C:/Program Files/nvim/share/nvim"
Run :checkhealth for more info
nvim -u NORC:au WinNew * wincmd p
:h help
:q
Program crashes
Help window exits normally
The reason why this crashes for Nvim and not for Vim, is that Nvim has code in place that fixes another issue. That earlier bug was never fixed in Vim, though.
Reference: https://github.com/neovim/neovim/pull/7431
The problem here is that we unconditionally use the returned window of get_snapshot_focus(SNAP_HELP_IDX). But by that time it's invalid already!
Here's what happens:
:echo win_getid()):h h makes a snapshot of the current frames (still only one window (1000)) and then splits the current window in two, placing the new window with ID 1001 at the top.motion.txt gets opened.curbuf is set to bad_wp->w_buffer and becomes a NULL pointer.check_cursor() uses curbuf.* thread #1, queue = 'com.apple.main-thread', stop reason = step in
frame #0: 0x0000000100059082 nvim`check_cursor_lnum at cursor.c:334
331 */
332 void check_cursor_lnum(void)
333 {
-> 334 if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
335 /* If there is a closed fold at the end of the file, put the cursor in
336 * its first line. Otherwise in the last line. */
337 if (!hasFolding(curbuf->b_ml.ml_line_count,
Target 0: (nvim) stopped.
(lldb) p curwin
(win_T *) $1 = 0x0000000001002a00
(lldb) p curbuf
(buf_T *) $2 = 0x0000000000000000
My suggestion:
diff --git i/src/nvim/window.c w/src/nvim/window.c
index 609d8f1b4..441d06395 100644
--- i/src/nvim/window.c
+++ w/src/nvim/window.c
@@ -2425,7 +2425,7 @@ int win_close(win_T *win, bool free_buf)
if (help_window) {
// Closing the help window moves the cursor back to the original window.
win_T *tmpwp = get_snapshot_focus(SNAP_HELP_IDX);
- if (tmpwp != NULL) {
+ if (tmpwp != NULL && win_valid(tmpwp)) {
wp = tmpwp;
}
}
The code after this block makes sure that a valid win is used.
Most helpful comment
The reason why this crashes for Nvim and not for Vim, is that Nvim has code in place that fixes another issue. That earlier bug was never fixed in Vim, though.
Reference: https://github.com/neovim/neovim/pull/7431
The problem here is that we unconditionally use the returned window of
get_snapshot_focus(SNAP_HELP_IDX). But by that time it's invalid already!Here's what happens:
:echo win_getid()):h hmakes a snapshot of the current frames (still only one window (1000)) and then splits the current window in two, placing the new window with ID 1001 at the top.motion.txtgets opened.curbufis set tobad_wp->w_bufferand becomes a NULL pointer.check_cursor()usescurbuf.My suggestion:
The code after this block makes sure that a valid win is used.