noib3/nvim-oxi

Segmentation fault on `nvim-0.9` when using `Buffer.get_lines()`

Closed this issue · 4 comments

I recently updated my neovim nightly version, everything seem to work except using Buffer.get_lines() segfaults w/:

2022-12-14-175341_538x108_scrot

Here's a minimal code from api example that reproduces the error:

use nvim_oxi::api::{self, opts::*, types::*, Buffer};
use nvim_oxi::{self as oxi};

#[oxi::module]
fn api() -> oxi::Result<()> {
    // Create a new `Greetings` command.
    let opts = CreateCommandOpts::builder()
        .bang(true)
        .desc("shows a greetings message")
        .nargs(CommandNArgs::ZeroOrOne)
        .build();

    let greetings = |args: CommandArgs| {
        let who = args.args.unwrap_or("from Rust".to_owned());
        let bang = if args.bang { "!" } else { "" };
        print!("Hello {}{}", who, bang);
        Ok(())
    };

    api::create_user_command("Greetings", greetings, &opts)?;

    // Remaps `hi` to `hello` in insert mode.
    api::set_keymap(Mode::Insert, "hi", "hello", &Default::default())?;

    // This line segfaults
    let _ = Buffer::current().get_lines(1..10, true)?;

    Ok(())
}
# Cargo.toml
[dependencies]
nvim-oxi = { version = "0.2.2", features = ["neovim-nightly"]  }

nvim-oxi version: 0.2.2

Neovim version that segfaults:

NVIM v0.9.0-dev-506+g090048bec
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/gcc-10 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -DNVIM_TS_HAS_SET_ALLOCATOR -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/runner/work/neovim/neovim/build/cmake.config -I/home/runner/work/neovim/neovim/src -I/home/runner/work/neovim/neovim/.deps/usr/include -I/usr/include -I/home/runner/work/neovim/neovim/build/src/nvim/auto -I/home/runner/work/neovim/neovim/build/include
Compiled by runner@fv-az246-948

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/share/nvim"

Run :checkhealth for more info

Neovim version that works:

NVIM v0.8.1
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by runner@fv-az178-366

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/share/nvim"

Run :checkhealth for more info

OS:


        /\         krivah@arch
       /  \        OS:        Arch Linux
      /\   \       KERNEL:    Linux 5.15.80-1-lts
     /  __  \      UPTIME:    13 hours, 43 minutes
    /  (  )  \     PACKAGES:  2034
   / __|  |__\\    SHELL:     zsh
  /.`        `.\   WM:        bspwm

I second this. I also have a similar issue with api::list_wins() crashing as soon as we iterate on the result.

I have tried looking into the code of both neovim and nvim-oxi to see what changed about these two functions (I also found that list_tabpages() has the same issue), and see literally no difference between 0.8 and nightly that could explain what's happening here.

Even more dumbfounding, some other very similar functions (for example list_bufs()) behave correctly. I'm a bit lost here.

This merge neovim/neovim#19877 probably broke Buffer.get_lines() not sure about list_tabpages() or list_wins()

After more digging: it's only list_tabpages() that is broken, but list_wins() calls the same function. And it's not always broken. Only during startup, if you load the plugin right away. My guess is there's a global variable that is still uninitialized at that point, and this may be neovim's fault (although it should be possible to protect nvim-oxi from this somehow).

Anyway, it seems a bunch of other stuff is currently broken on nightly. A few tests are already failing, and I've found a few other cases that aren't covered by tests. Notably, set_hl() is broken (complains about strikethrough not being a boolean), and create_autocmd always has once set to true somehow. I've looked into the code to see if the structures' layouts have changed, but I don't think they have. This may be a more general issue with how booleans are handled somewhere.