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

buffer completion for large CJK document leads to segmentation fault of neovim #560

Closed
2 tasks done
moetayuko opened this issue Dec 14, 2024 · 3 comments
Closed
2 tasks done
Labels
bug Something isn't working

Comments

@moetayuko
Copy link

Make sure you have done the following

  • I have updated to the latest version of blink.cmp
  • I have read the README

Bug Description

I'm using LazyVim, which enables the buffer completion source for blink.cmp
https://github.com/LazyVim/LazyVim/blob/dc4345a5ee23ffb4aad50c01eca49d5bc47a96c3/lua/lazyvim/plugins/extras/coding/blink.lua#L76

when editing a large CJK document and modifying a long sentence in insert mode, neovim crashes with a segmentation fault right after the modification.
I can no longer reproduce the crash once I disable buffer from completion sources, so I suspect there's something wrong with it

this is a random large Chinese document for reproducing the issue
https://github.com/ArcturusZhang/Classical-Mechanics-Lecture-Notes/raw/refs/heads/master/chapter/chapter2.tex

here is a cast for the issue
asciicast

below is the stack trace

#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:76
No locals.
#1  0x0000650858389eea in xstrdup (str=0x0) at /usr/src/debug/neovim/neovim/src/nvim/memory.c:469
No locals.
#2  0x0000650858356744 in nlua_luv_thread_common_cfpcall (lstate=0x72535a3e0380, nargs=1, nresult=-1,
    flags=1, is_callback=is_callback@entry=false) at /usr/src/debug/neovim/neovim/src/nvim/lua/executor.c:279
        error = <optimized out>
        retval = <optimized out>
        top = 2
        status = 2
#3  0x0000650858356895 in nlua_luv_thread_cfpcall (lstate=<optimized out>, nargs=<optimized out>,
    nresult=<optimized out>, flags=<optimized out>)
    at /usr/src/debug/neovim/neovim/src/nvim/lua/executor.c:244
No locals.
#4  0x0000725360b2b644 in luv_work_cb (L=0x72535a3e0380) at /usr/src/debug/libluv/luv-1.48.0-2/src/work.c:107
        i = <optimized out>
        req = <optimized out>
        work = 0x6508705fac00
        ctx = <optimized out>
        lctx = 0x72535a3ea4d8
        top = 0
#5  0x0000725360a17f06 in lj_BC_FUNCC () at buildvm_x86.dasc:857
No locals.
#6  0x0000725360a2c0aa in lua_pcall (L=L@entry=0x72535a3e0380, nargs=nargs@entry=1,
    nresults=nresults@entry=0, errfunc=errfunc@entry=0)
    at /usr/src/debug/luajit/LuaJIT-fe71d0fb54ceadfb5b5f3b6baf29e486d97f6059/src/lj_api.c:1122
        g = 0x72535a3e03e0
        oldh = 0 '\000'
        ef = <optimized out>
        status = <optimized out>
#7  0x00006508583566e7 in nlua_luv_thread_common_cfpcall (lstate=lstate@entry=0x72535a3e0380,
    nargs=nargs@entry=1, nresult=nresult@entry=0, flags=flags@entry=1, is_callback=is_callback@entry=false)
    at /usr/src/debug/neovim/neovim/src/nvim/lua/executor.c:263
        retval = <optimized out>
        top = 2
        status = <optimized out>
#8  0x0000650858356895 in nlua_luv_thread_cfpcall (lstate=lstate@entry=0x72535a3e0380, nargs=nargs@entry=1,
    nresult=nresult@entry=0, flags=flags@entry=1) at /usr/src/debug/neovim/neovim/src/nvim/lua/executor.c:244
No locals.
#9  0x00006508583568dd in nlua_luv_thread_cfcpcall (lstate=0x72535a3e0380, func=<optimized out>,
    ud=0x6508705fac00, flags=1) at /usr/src/debug/neovim/neovim/src/nvim/lua/executor.c:252
        retval = <optimized out>
#10 0x0000725360b2b8aa in luv_work_cb_wrapper (req=0x6508705fac00)
    at /usr/src/debug/libluv/luv-1.48.0-2/src/work.c:155
        work = 0x6508705fac00
        L = 0x72535a3e0380
        lctx = <optimized out>
        i = <optimized out>
#11 0x000072536090030a in worker (arg=0x0) at src/threadpool.c:122
        w = 0x6508705fac58
        q = 0x6508705fac70
        is_slow_work = 0

Relevant configuration

vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()

require("lazy.minit").repro({
	spec = {
		{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
		-- uncomment the following block avoids segmentation fault
		-- {
		-- 	"saghen/blink.cmp",
		-- 	opts = {
		-- 		sources = {
		-- 			default = function()
		-- 				return { "lsp", "path", "snippets" }
		-- 			end,
		-- 		},
		-- 	},
		-- },
	},
})

neovim version

v0.10.2

blink.cmp version: branch, tag, or commit

v0.7.6

@moetayuko moetayuko added the bug Something isn't working label Dec 14, 2024
@itepechi
Copy link

itepechi commented Dec 14, 2024

Do we really need this '+ 1'?
It seems that removing this line solves the problem.

if char:match('[%w_\\-]') == nil then
start_col = start_col + 1
break
end

It also produces a (seemingly) weird chunk:

Typing ipsum on a text:

Lorem {cursor} dolor sit amet, consectetur adipiscing elit. Gravida mus sociosqu

with start_col = start_col + 1:

{
  _line = "Lorem i  dolor sit amet, consectetur adipiscing elit. Gravida mus sociosqu"
}

without start_col = start_col + 1:

{                                                                                                                           
  _line = "Lorem   dolor sit amet, consectetur adipiscing elit. Gravida mus sociosqu"                                        
}  

Typing bar baz on a text:

foo("{cursor}")

with start_col = start_col + 1:

{                                                                                                                           
  _line = 'foo("b ")'                                                                                                        
}                                                                                                                           
{                                                                                                                           
  _line = 'foo("bar b ")'                                                                                                    
}    

without start_col = start_col + 1:

{                                                                                                                           
  _line = 'foo(" ")'                                                                                                         
}                                                                                                                           
{                                                                                                                           
  _line = 'foo("bar  ")'                                                                                                     
}  

@moetayuko
Copy link
Author

Do we really need this '+ 1'? It seems that removing this line solves the problem.

confirmed

@Saghen Saghen closed this as completed in d682165 Dec 16, 2024
@Saghen
Copy link
Owner

Saghen commented Dec 16, 2024

Thanks for debugging this @itepechi!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants