kevinhwang91 / nvim-ufo

Not UFO in the sky, but an ultra fold in Neovim.
BSD 3-Clause "New" or "Revised" License
2.16k stars 37 forks source link

TreeSitter provider segfaults on NVIM v0.10.0 on WSL2 #221

Closed Raizento closed 1 month ago

Raizento commented 1 month ago

Neovim version (nvim -v | head -n1)

NVIM v0.10.0

Operating system/version

5.15.146.1-microsoft-standard-WSL2 / Ubuntu 22.04.4 LTS

How to reproduce the issue

-- Settings
vim.o.foldcolumn = '1' 
vim.o.foldlevel = 99 
vim.o.foldlevelstart = 99
vim.o.foldenable = true

-- Install Lazy
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", -- latest stable release
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

require("lazy").setup({
  {
    "kevinhwang91/nvim-ufo",
    dependencies = {
      "kevinhwang91/promise-async",
      "nvim-treesitter/nvim-treesitter",
    },

    config = function()
      require("ufo").setup({
        provider_selector = function(bufnr, filetype, buftype)
          return { "treesitter", "indent" }
        end,
      })
    end,
  },
})

Expected behavior

UFO should start and not crash NVIM.

Actual behavior

When opening a file for editing in which UFO gets loaded, NVIM crashes with May 16 17:00:16.568 ERROR Error: Process exited with error code 139

Error code 139 seems to indicate a segfault.

Some changes to treesitter have been implemented with v0.10.0, see :h news when running v0.10.0. These new changes are probably the root of this issue.

kevinhwang91 commented 1 month ago

can't reproduce it, need more information.

Raizento commented 1 month ago

I have been testing around a bit more: on my WSL2 setup it crashes consistently when opening any file in which folds are present. The smallest file I got it to crash with was this:

void main() {
}

However, I have now tried running it on a pure Linux system (Linux endeavour 6.6.30-2-lts) and it runs flawlessly there.

I have also tried running TreeSitter by itself to see if it was causing the issue. Running TreeSitter alone did not crash on my WSL2 instance.

What more information do you need? Since NVIM fails with a segfault, it's kind of hard to get any logs produced by UFO and NVIM. Will try to get any information you deem useful though.

I am currently trying to get a core dump of NVIM but WSL2 is giving me a hard time...

kevinhwang91 commented 1 month ago

Change Build type to Debug for neovim in building and get core dump.

Raizento commented 1 month ago
> gdb nvim core
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from nvim...

warning: Can't open file anon_inode:[io_uring] which was expanded to anon_inode:[io_uring] during file-backed mapping note processing

warning: Can't open file anon_inode:[io_uring] which was expanded to anon_inode:[io_uring] during file-backed mapping note processing

warning: Can't open file anon_inode:[io_uring] which was expanded to anon_inode:[io_uring] during file-backed mapping note processing

warning: Can't open file anon_inode:[io_uring] which was expanded to anon_inode:[io_uring] during file-backed mapping note processing
[New LWP 36203]
[New LWP 36205]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `{HOME_DIR}/nvim-debug-build/neovim/build/bin/nvim --embed'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00005555558001eb in changed_window_setting (wp=0x0)
    at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/move.c:544
544       wp->w_lines_valid = 0;
[Current thread is 1 (Thread 0x7ffff7c81b80 (LWP 36203))]

So, it seems to be some sort of problem in NVIM when using UFO. The function causing the issue also seems to be related to folding:

// Call this function when some window settings have changed, which require
// the cursor position, botline and topline to be recomputed and the window to
// be redrawn.  E.g, when changing the 'wrap' option or folding.
void changed_window_setting(win_T *wp)
{
  wp->w_lines_valid = 0;
  changed_line_abv_curs_win(wp);
  wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP|VALID_TOPLINE);
  redraw_later(wp, UPD_NOT_VALID);
}
kevinhwang91 commented 1 month ago

Please show the backtrace, I guess is a building issue for WSL2

Raizento commented 1 month ago
#0  0x0000559ddbfed1eb in changed_window_setting (wp=0x0) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/move.c:544
#1  0x0000559ddc20ab96 in lj_vm_ffi_call ()
#2  0x0000559ddc230f27 in lj_ccall_func (L=<optimized out>, cd=<optimized out>) at lj_ccall.c:1187
#3  0x0000559ddc2062dd in lj_cf_ffi_meta___call (L=0x7f8819b9c380) at lib_ffi.c:230
#4  0x0000559ddc208736 in lj_BC_FUNCC ()
#5  0x0000559ddc1f489c in lua_pcall (L=0x7f8819b9c380, nargs=<optimized out>, nresults=0, errfunc=<optimized out>) at lj_api.c:1122
#6  0x0000559ddbf8fd60 in nlua_pcall (lstate=0x7f8819b9c380, nargs=0, nresults=0) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/lua/executor.c:173
#7  0x0000559ddbf90625 in nlua_schedule_event (argv=0x7ffec6e60b08) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/lua/executor.c:371
#8  0x0000559ddc0dcc82 in state_handle_k_event () at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/state.c:119
#9  0x0000559ddc0076b2 in nv_event (cap=0x7ffec6e60ca0) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/normal.c:6586
#10 0x0000559ddbffb1e8 in normal_execute (state=0x7ffec6e60c30, key=-26365) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/normal.c:1229
#11 0x0000559ddc0dcc12 in state_enter (s=0x7ffec6e60c30) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/state.c:101
#12 0x0000559ddbff9414 in normal_enter (cmdwin=false, noexmode=false) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/normal.c:518
#13 0x0000559ddbf9f25a in main (argc=3, argv=0x7ffec6e61008) at {HOME_DIR}/nvim-debug-build/neovim/src/nvim/main.c:664
kevinhwang91 commented 1 month ago

https://github.com/kevinhwang91/nvim-ufo/blob/414e3d8a685efba7bcaff05feb5ab22b309a011b/lua/ufo/wffi.lua#L40

comment this line and try again. I have no idea why it caused the WSL2 crash. You can bisect the code base of neovim. I don't have WSL2 env.

waynerv commented 1 month ago

I can reproduces this issue on macOS 14.2.1 intel with the same config above to open a golang file, using neovim distributed by homebrew:

❯ nvim -u config.lua etcd/etcdctl/main.go
# Crashes immediately after opening the buffer.
❯ echo $?
139
❯ nvim --version
NVIM v0.10.0
Build type: Release
LuaJIT 2.1.1713773202
Run "nvim -V1 -v" for more info
kevinhwang91 commented 1 month ago

I can reproduces this issue on macOS 14.2.1 intel with the same config above to open a golang file, using neovim distributed by homebrew:

❯ nvim -u config.lua etcd/etcdctl/main.go
# Crashes immediately after opening the buffer.
❯ echo $?
139
❯ nvim --version
NVIM v0.10.0
Build type: Release
LuaJIT 2.1.1713773202
Run "nvim -V1 -v" for more info

Actually, this config is not mini config. Please provide the mini config so that I can debug.

Raizento commented 1 month ago

https://github.com/kevinhwang91/nvim-ufo/blob/414e3d8a685efba7bcaff05feb5ab22b309a011b/lua/ufo/wffi.lua#L40

comment this line and try again. I have no idea why it caused the WSL2 crash. You can bisect the code base of neovim. I don't have WSL2 env.

This seems to be working. I have been searching through the codebase of UFO and NVIM right now and this stood out to me:

UFO uses the changed_window_setting() without any arguments. In NVIM v0.9.5, there is a function present with exactly that signature:

void changed_window_setting(void)
{
  changed_window_setting_win(curwin);
}

However, it seems that this method has been removed in v0.10.0, causing problems with the pointer to curwin since no pointer has been supplied:

src/nvim/mbyte.c|2882 col 3| changed_window_setting_all();
src/nvim/fold.c|480 col 3| changed_window_setting(wp);
src/nvim/fold.c|495 col 5| changed_window_setting(curwin);
src/nvim/fold.c|664 col 5| changed_window_setting(wp);
src/nvim/fold.c|738 col 7| changed_window_setting(wp);
src/nvim/fold.c|1271 col 7| changed_window_setting(wp);
src/nvim/fold.c|2119 col 5| changed_window_setting(wp);
src/nvim/diff.c|1462 col 3| changed_window_setting(wp);
src/nvim/diff.c|1528 col 7| changed_window_setting(wp);
src/nvim/normal.c|2945 col 7| changed_window_setting(curwin);
src/nvim/normal.c|3116 col 11| changed_window_setting(wp);
src/nvim/normal.c|3120 col 5| changed_window_setting(curwin);
src/nvim/api/extmark.c|1240 col 5| changed_window_setting(win);
src/nvim/api/extmark.c|1289 col 5| changed_window_setting(win);
src/nvim/api/vim.c|2314 col 5| changed_window_setting(wp);
src/nvim/eval/window.c|889 col 3| changed_window_setting(curwin);
src/nvim/ex_cmds.c|4283 col 5| changed_window_setting(curwin);
src/nvim/option.c|1940 col 9| changed_window_setting(curwin);
src/nvim/option.c|1971 col 9| changed_window_setting(curwin);
src/nvim/option.c|3030 col 7| changed_window_setting(win);
src/nvim/move.c|542 col 6| void changed_window_setting(win_T *wp)
src/nvim/move.c|550 col 10| /// Call changed_window_setting() for every window.
src/nvim/move.c|551 col 6| void changed_window_setting_all(void)
src/nvim/move.c|554 col 5| changed_window_setting(wp);

Indeed, I tried the following and it does not crash anymore:

wffi.lua

---
---@param winid number
function M.clearFolds(winid)
    local wp = findWin(winid)
    C.clearFolding(wp)
    C.changed_window_setting(wp)
end

-- other lua code here

local function init()
    ffi = require('ffi')
    setmetatable(M, {__index = ffi})
    C = ffi.C
    utils = require('ufo.utils')
    if utils.has08() then
        ffi.cdef([[
            typedef int32_t linenr_T;
        ]])
    else
        ffi.cdef([[
            typedef long linenr_T;
        ]])
    end
    ffi.cdef([[
        typedef struct window_S win_T;
        typedef int colnr_T;

        typedef struct {} Error;
        win_T *find_window_by_handle(int window, Error *err);

        typedef struct {
            linenr_T lnum;
            colnr_T col;
            colnr_T coladd;
        } pos_T;

        void clearFolding(win_T *win);
        void changed_window_setting(win_T *wp);
        void foldCreate(win_T *wp, pos_T start, pos_T end);

        int plines_win(win_T *wp, linenr_T lnum, bool winheight);
        int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight);
    ]])
    CPos_T = ffi.typeof('pos_T')
end
Raizento commented 1 month ago

Having a look at the master branch again... it seems that change has already been implemented. Which is weird since I updated all my plugins at least 4 times yesterday. @waynerv see if updating fixes the issue.

kevinhwang91 commented 1 month ago

Your ufo code base is stale.

waynerv commented 1 month ago

After deleting all Neovim cache and the lazy lock file, this issue was resolved.

xiantang commented 1 month ago

ys should update UFO version ![Uploading image.png…]()

xiantang commented 1 month ago

image