Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash: vim.uv.walk #25043

Open
bukzor opened this issue Sep 7, 2023 · 8 comments
Open

Crash: vim.uv.walk #25043

bukzor opened this issue Sep 7, 2023 · 8 comments
Labels
bug-crash issue reporting a crash or segfault event-loop lua stdlib
Milestone

Comments

@bukzor
Copy link

bukzor commented Sep 7, 2023

Problem

Using vim.loop.walk in any way results in nvim crashing with a segmentation fault (same for vim.uv.walk).

Steps to reproduce

$ env -i nvim --clean -es +'lua vim.loop.walk(function() print("ohai") end)'
vim: src/loop.c:85: luv_walk_cb: Assertion `data && data->ref < 0x1000000' failed.
Aborted (core dumped)

I got that particular message from v0.4.4. Newer versions crash silently (seems worse, to me).

Expected behavior

Print ohai a bunch of times.

Neovim version (nvim -v)

NVIM v0.10.0-dev-1046+g3afbf4745, NVIM v0.9.1, NVIM v0.4.4

Vim (not Nvim) behaves the same?

n/a

Operating system/version

$ uname -a Linux penguin 5.15.117-19679-g172023e664f7 #1 SMP PREEMPT Fri Aug 18 18:07:47 PDT 2023 x86_64 GNU/Linux

Terminal name/version

hterm

$TERM environment variable

n/a

Installation

source, brew, debian (respectively)

@bukzor bukzor added the bug issues reporting wrong behavior label Sep 7, 2023
@bukzor bukzor changed the title segfault: vim.loop.walk segfault: vim.uv.walk Sep 7, 2023
@bukzor
Copy link
Author

bukzor commented Sep 7, 2023

All versions of neovim (that I have) have a vim.loop.walk but some newer versions also have a vim.uv.walk. The behavior is identical though regardless of which alias is used.

@bfredl
Copy link
Member

bfredl commented Sep 7, 2023

Libluvs wrapper around uv_walk assumes that libluv (the lua bindings) make exclusive use of the uv event loop. This leads to a crash in nvim as libluv then cannot understand handles that is owned by nvim core, not libluv.

This could be fixed in libluv at the price of making the implementation more complicated. Alternatively, we could change vim.uv.walk to just immediately throw an error.

So I am curious what the usecase of using uv.walk() is here. There might be another way to solve the underlying problem.

@bukzor
Copy link
Author

bukzor commented Sep 8, 2023

My intent was to iterate through the existing timers and methodically delete them, so as to find which of my plugins is periodically running chdir($HOME). I already did this exercise with the autocmd/augroups but the behavior persisted, and eventually I came to realize the behavior comes from a uv timer. This API looked ideal for that purpose.

While tinkering with this idea I had imagined / hoped for a :Telescope event-loop extension which would let us browse and control timers the way it already does autocmds -- from an end-user perspective they're nearly identical things. vim.uv.walk would be critical for enabling such a thing.

@bukzor
Copy link
Author

bukzor commented Sep 8, 2023

Libluvs wrapper around uv_walk assumes that libluv (the lua bindings) make exclusive use of the uv event loop.

Would you kindly point out the relevant code? The function I saw takes the event loop as the first argument, so I had expected a method (vim.uv:walk(function...end)).

@bfredl
Copy link
Member

bfredl commented Sep 8, 2023

Would you kindly point out the relevant code? The function I saw takes the event loop as the first argument, so I had expected a method (vim.uv:walk(function...end)).

It's luv_walk in src/loop.c. libluv keeps track of one uv event loop per lua thread. Indepdendent luv event loops are possible, but they must then run in a separate thread ( vim.uv.new_thread(...)).

While tinkering with this idea I had imagined / hoped for a :Telescope event-loop extension which would let us browse and control timers the way it already does autocmds -- from an end-user perspective they're nearly identical things. vim.uv.walk would be critical for enabling such a thing.

Debugging the event loop is a relevant usecase. But it is going to require some cooperation from nvim core. Such an interface would ideally show and identify uv handles regardless if they come from libluv or nvim core (often wrappers for jobs and timers for vimscript and also RPC channels).

@bukzor
Copy link
Author

bukzor commented Sep 8, 2023

Is the nvim-core loop exposed to lua at all, currently?

The convention of one-loop-per-lua seems baked into luv pretty deep... are you picturing a major revision to luv or would you not use it for this?

@bfredl
Copy link
Member

bfredl commented Sep 8, 2023

The convention of one-loop-per-lua seems baked into luv pretty deep... are you picturing a major revision to luv or would you not use it for this?

No not at all. I'm just saying implementing the debugging functionality you want is going to be a bit more involved than just an isolated change to just vim.uv.walk . It is definitely something worth doing and a welcome contribution, I just want to be clear upfront with the scope of the effort needed.

@bukzor
Copy link
Author

bukzor commented Sep 11, 2023 via email

@zeertzjq zeertzjq added bug-crash issue reporting a crash or segfault event-loop and removed bug issues reporting wrong behavior labels Sep 16, 2023
@zeertzjq zeertzjq added the lua stdlib label Feb 16, 2024
@zeertzjq zeertzjq changed the title segfault: vim.uv.walk Crash: vim.uv.walk Feb 16, 2024
@zeertzjq zeertzjq added this to the backlog milestone Mar 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug-crash issue reporting a crash or segfault event-loop lua stdlib
Projects
None yet
Development

No branches or pull requests

3 participants