neovim / neovim

Vim-fork focused on extensibility and usability
https://neovim.io
Other
83.32k stars 5.7k forks source link

memory leak in nlua_init_state #24512

Open justinmk opened 1 year ago

justinmk commented 1 year ago

Problem

observed in https://github.com/neovim/neovim/pull/24508

RUN      T1 autocmd api nvim_create_autocmd validation: 26.31 ms OK
==================== File /home/runner/work/neovim/neovim/build/log/ubsan.11475 ====================
= 
= =================================================================
= ==11475==ERROR: LeakSanitizer: detected memory leaks
= 
= Direct leak of 1023 byte(s) in 1 object(s) allocated from:
=     #0 0x55b7ca976d9e in __interceptor_malloc (/home/runner/work/neovim/neovim/build/bin/nvim+0xcc2d9e) (BuildId: 678faec75bad2a7cf6b16e33a449ef5ed2707621)
=     #1 0x55b7cc312278 in strbuf_init /home/runner/work/neovim/neovim/src/cjson/strbuf.c:61:14
=     #2 0x55b7cc303c04 in json_create_config /home/runner/work/neovim/neovim/src/cjson/lua_cjson.c:507:5
=     #3 0x55b7cc302015 in lua_cjson_new /home/runner/work/neovim/neovim/src/cjson/lua_cjson.c:1620:5
=     #4 0x55b7cb5c6385 in nlua_state_add_stdlib /home/runner/work/neovim/neovim/src/nvim/lua/stdlib.c:632:3
=     #5 0x55b7cb5abce9 in nlua_init_state /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:874:3
=     #6 0x55b7cb5ab84f in nlua_run_script /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:837:19
=     #7 0x55b7ca9b2796 in main /home/runner/work/neovim/neovim/src/nvim/main.c:263:5
=     #8 0x7efc9395fd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)
= 
= Direct leak of 480 byte(s) in 1 object(s) allocated from:
=     #0 0x55b7ca976f88 in __interceptor_calloc (/home/runner/work/neovim/neovim/build/bin/nvim+0xcc2f88) (BuildId: 678faec75bad2a7cf6b16e33a449ef5ed2707621)
=     #1 0x55b7cc46ff10 in uv__calloc /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/uv-common.c:93:10
=     #2 0x55b7cc4818c0 in uv_loop_init /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/unix/loop.c:40:43
=     #3 0x55b7cc38b7e0 in luaopen_luv /home/runner/work/neovim/neovim/.deps/build/src/luv/src/luv.c:848:11
=     #4 0x55b7cb5bcfba in nlua_common_vim_init /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:579:3
=     #5 0x55b7cb5abcd8 in nlua_init_state /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:872:3
=     #6 0x55b7cb5ab84f in nlua_run_script /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:837:19
=     #7 0x55b7ca9b2796 in main /home/runner/work/neovim/neovim/src/nvim/main.c:263:5
=     #8 0x7efc9395fd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)
= 
= Direct leak of 128 byte(s) in 1 object(s) allocated from:
=     #0 0x55b7ca9771c6 in __interceptor_realloc (/home/runner/work/neovim/neovim/build/bin/nvim+0xcc31c6) (BuildId: 678faec75bad2a7cf6b16e33a449ef5ed2707621)
=     #1 0x55b7cc46ff4b in uv__realloc /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/uv-common.c:98:12
=     #2 0x55b7cc46ff8c in uv__reallocf /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/uv-common.c:106:12
=     #3 0x55b7cc477956 in maybe_resize /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/unix/core.c:877:14
=     #4 0x55b7cc47781f in uv__io_start /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/unix/core.c:911:3
=     #5 0x55b7cc48504f in uv__signal_loop_once_init /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/unix/signal.c:275:3
=     #6 0x55b7cc4852f8 in uv_signal_init /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/unix/signal.c:324:9
=     #7 0x55b7cc48[36](https://github.com/neovim/neovim/actions/runs/5697665982/job/15450625232?pr=24508#step:12:37)8f in uv__process_init /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/unix/process.c:87:9
=     #8 0x55b7cc481a89 in uv_loop_init /home/runner/work/neovim/neovim/.deps/build/src/libuv/src/unix/loop.c:85:9
=     #9 0x55b7cc38b7e0 in luaopen_luv /home/runner/work/neovim/neovim/.deps/build/src/luv/src/luv.c:848:11
=     #10 0x55b7cb5bcfba in nlua_common_vim_init /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:579:3
=     #11 0x55b7cb5abcd8 in nlua_init_state /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:872:3
=     #12 0x55b7cb5ab84f in nlua_run_script /home/runner/work/neovim/neovim/src/nvim/lua/executor.c:8[37](https://github.com/neovim/neovim/actions/runs/5697665982/job/15450625232?pr=24508#step:12:38):19
=     #13 0x55b7ca9b2796 in main /home/runner/work/neovim/neovim/src/nvim/main.c:263:5
=     #14 0x7efc9395fd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)
= 
= SUMMARY: AddressSanitizer: 1631 byte(s) leaked in 3 allocation(s).
====================================================================================================
nan ms test/helpers.lua:328: Found runtime errors in logfile(s): /home/runner/work/neovim/neovim/build/log/ubsan.11475

stack traceback:
    test/helpers.lua:328: in function 'check_logs'
    test/functional/helpers.lua:944: in function <test/functional/helpers.lua:9[43](https://github.com/neovim/neovim/actions/runs/5697665982/job/15450625232?pr=24508#step:12:44)>

RUN      T2 autocmd api nvim_create_autocmd doesnt leak when you use ++once: 22.13 ms OK
zeertzjq commented 1 year ago

I think there are two solutions:

  1. Override the Lua os.exit() function. For -ll override it with a function that calls nlua_free_all_mem() and exit(). For -l override it with a function that calls os_exit().
  2. Register nlua_free_all_mem() as an atexit() callback. Only works for -ll, as for -l all cleanup steps in os_exit() are needed to avoid leaking memory, and an atexit() callback cannot change exit code in case event_teardown() fails.
justinmk commented 1 year ago

Override the Lua os.exit() function.

I think that is appropriate. It's like print() which we also override.