diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2026-08-18 08:30:42 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-18 08:30:42 -0400 |
| commit | 1eae512285e7131f4bf48416f9d4b8b1124e223a (patch) | |
| tree | 31931f120f6f40758ba5d55b68c52756e0571c03 /src/nvim/lua/executor.c | |
| parent | f6bf814378c6e51aeecb8333040a78666b543392 (diff) | |
| download | rneovim-1eae512285e7131f4bf48416f9d4b8b1124e223a.tar.gz rneovim-1eae512285e7131f4bf48416f9d4b8b1124e223a.tar.bz2 rneovim-1eae512285e7131f4bf48416f9d4b8b1124e223a.zip | |
fix(lifecycle): Lua state not freed if free_all_mem() is re-entered #41366
Problem:
Leak reported by ASAN CI, always at Lua state init.
ERROR: LeakSanitizer: detected memory leaks
strbuf_init src/cjson/strbuf.c:62:22
json_create_config src/cjson/lua_cjson.c:635:5
lua_cjson_new src/cjson/lua_cjson.c:2060:5
nlua_state_add_stdlib src/nvim/lua/stdlib.c:840:3
nlua_state_init src/nvim/lua/executor.c:973:3
...
SUMMARY: AddressSanitizer: 1055 byte(s) leaked in 2 allocation(s).
Analysis:
`getout()` may run during `free_all_mem()` (that's why it checks
`!entered_free_all_mem`). If that happens, the second `os_exit()`
returns early from `free_all_mem()` then `exit()` is called and Lua
state is never closed.
Solution:
Always call `nlua_free_all_mem()` in the early-return case.
Diffstat (limited to 'src/nvim/lua/executor.c')
| -rw-r--r-- | src/nvim/lua/executor.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index bffa924d8f..402fbcd52f 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1061,12 +1061,14 @@ static lua_State *nlua_init_state(bool thread) return lstate; } +/// Disposes global Lua state. Idempotent, harmless if called multiple times. void nlua_free_all_mem(void) { if (!global_lstate) { return; } lua_State *lstate = global_lstate; + global_lstate = NULL; nlua_unref_global(lstate, require_ref); nlua_common_free_all_mem(lstate); nlua_treesitter_free(); |