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

Neovim sometimes crashes on lua_getallocf called from json5.so #5

Closed
jedrzejboczar opened this issue Oct 16, 2024 · 2 comments
Closed

Comments

@jedrzejboczar
Copy link

Hi, I am using lua-json5 for nvim-dap to load launch.json. I noticed that once in a while when I load dap configurations for the first time the whole Neovim crashes. From core dump using coredumpctl I can see the following:

Stack trace of thread 244848:
#0  0x000070e5d6e4c14d lua_getallocf (libluajit-5.1.so.2 + 0x1b14d)
#1  0x000070e5be22aaf8 n/a (/home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so + 0x1caf8)
ELF object binary architecture: AMD x86-64

and in GDB using bt:

(gdb) bt
#0  0x000070e5d6e4c14d in lua_getallocf (L=0x70e5cb9d4dd8, ud=0x7fff7102d600) at /usr/src/debug/luajit/LuaJIT-97813fb924edf822455f91a5fbbdfdb349e5984f/src/lj_api.c:1309
#1  0x000070e5be22aaf8 in ?? () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
#2  0x000070e5be236103 in ?? () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
#3  0x000070e5be232a7c in ?? () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
#4  0x000070e5be22a64c in ?? () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
#5  0x000070e5be2393d8 in ?? () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
#6  0x000070e5d6e37f06 in lj_BC_FUNCC () at buildvm_x86.dasc:857
#7  0x000070e5d6e4c0aa in lua_pcall (L=L@entry=0x70e5d6f5e380, nargs=nargs@entry=0, nresults=nresults@entry=1, errfunc=errfunc@entry=-2) at /usr/src/debug/luajit/LuaJIT-97813fb924edf822455f91a5fbbdfdb349e5984f/src/lj_api.c:1122
#8  0x0000594e115bff4e in nlua_pcall (nresults=1, lstate=0x70e5d6f5e380, nargs=0) at /usr/src/debug/neovim-git/neovim/src/nvim/lua/executor.c:174
#9  nlua_call_ref.constprop.0 (ref=<optimized out>, name=name@entry=0x0, args=..., err=err@entry=0x7fff7102e0e0, arena=<optimized out>, mode=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/lua/executor.c:1608
#10 0x0000594e1130951f in map_execute_lua (may_repeat=true) at /usr/src/debug/neovim-git/neovim/src/nvim/getchar.c:3183
#11 0x0000594e113dfcbb in nv_colon (cap=0x7fff7102e2e0) at /usr/src/debug/neovim-git/neovim/src/nvim/normal.c:3174
#12 0x0000594e113dc3e6 in normal_execute (state=0x7fff7102e270, key=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/normal.c:1235
#13 0x0000594e114d691b in state_enter (s=0x7fff7102e270) at /usr/src/debug/neovim-git/neovim/src/nvim/state.c:102
#14 0x0000594e113d900a in normal_enter (cmdwin=<optimized out>, noexmode=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/normal.c:521
#15 0x0000594e11169187 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/main.c:660

I don't have debug symbols for lua-json5 so that doesn't tell much, but GDB with debuginfod could point to the following:

#0  0x000070e5d6e4c14d in lua_getallocf (L=0x70e5cb9d4dd8, ud=0x7fff7102d600) at /usr/src/debug/luajit/LuaJIT-97813fb924edf822455f91a5fbbdfdb349e5984f/src/lj_api.c:1309
1309      if (ud) *ud = g->allocd;

so the question is what part of lua-json5 calls lua_getallocf with invalid arguments.

I will try to compile lua-json5 with debug symbols so that the next time it happens I can say more.

@jedrzejboczar
Copy link
Author

Here's stack trace with debug info:

(gdb) bt f
#0  0x000071b9f6d3014d in lua_getallocf (L=0x71b9f53c11e0, ud=0x7ffe1d62a320) at /usr/src/debug/luajit/LuaJIT-97813fb924edf822455f91a5fbbdfdb349e5984f/src/lj_api.c:1309
        g = 0x3ff0000000000000
#1  0x000071b9f0b989a9 in mlua::lua::Lua::create_table_from () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
No symbol table info available.
#2  0x000071b9f0b9dc16 in <lua_json5::val::Value as mlua::value::IntoLua>::into_lua () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
No symbol table info available.
#3  0x000071b9f0ba14fc in lua_json5::parser::parse () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
No symbol table info available.
#4  0x000071b9f0b98541 in mlua::lua::Lua::create_function::{{closure}} () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
No symbol table info available.
#5  0x000071b9f0ba946f in mlua::lua::Lua::create_callback::call_callback () from /home/jb/.local/share/nvim/lazy/lua-json5/lua/json5.so
No symbol table info available.
#6  0x000071b9f6d1bf06 in lj_BC_FUNCC () at buildvm_x86.dasc:857
No locals.
#7  0x000071b9f6d300aa in lua_pcall (L=L@entry=0x71b9f6e43380, nargs=nargs@entry=0, nresults=nresults@entry=1, errfunc=errfunc@entry=-2) at /usr/src/debug/luajit/LuaJIT-97813fb924edf822455f91a5fbbdfdb349e5984f/src/lj_api.c:1122
#8  0x00005e59ece5824e in nlua_pcall (nresults=1, lstate=0x71b9f6e43380, nargs=0) at /usr/src/debug/neovim-git/neovim/src/nvim/lua/executor.c:174
#9  nlua_call_ref.constprop.0 (ref=<optimized out>, name=name@entry=0x0, args=..., err=err@entry=0x7ffe1d62ad90, arena=<optimized out>, mode=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/lua/executor.c:1608
#10 0x00005e59ecba159f in map_execute_lua (may_repeat=true) at /usr/src/debug/neovim-git/neovim/src/nvim/getchar.c:3183
#11 0x00005e59ecc77dbb in nv_colon (cap=0x7ffe1d62af90) at /usr/src/debug/neovim-git/neovim/src/nvim/normal.c:3174
#12 0x00005e59ecc744e6 in normal_execute (state=0x7ffe1d62af20, key=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/normal.c:1235
#13 0x00005e59ecd6eadb in state_enter (s=0x7ffe1d62af20) at /usr/src/debug/neovim-git/neovim/src/nvim/state.c:102
#14 0x00005e59ecc7110a in normal_enter (cmdwin=<optimized out>, noexmode=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/normal.c:521
#15 0x00005e59eca01187 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/neovim-git/neovim/src/nvim/main.c:660

though it probably doesn't tell much...
And si_addr = 0 so as far as I can understand this should be a null pointer dereference (https://sourceware.org/gdb/current/onlinedocs/gdb.html/Signals.html):

(gdb) p $_siginfo._sifields._sigfault
$4 = {
  si_addr = 0x0,
  _addr_lsb = 0,
  _addr_bnd = {
    _lower = 0x0,
    _upper = 0x0
  }
}

And for completeness:

(gdb) list
1304    }
1305
1306    LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
1307    {
1308      global_State *g = G(L);
1309      if (ud) *ud = g->allocd;
1310      return g->allocf;
1311    }
1312
1313    LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
(gdb) disassemble
Dump of assembler code for function lua_getallocf:
   0x000071b9f6d30140 <+0>:     endbr64
   0x000071b9f6d30144 <+4>:     mov    0x10(%rdi),%rax
   0x000071b9f6d30148 <+8>:     test   %rsi,%rsi
   0x000071b9f6d3014b <+11>:    je     0x71b9f6d30154 <lua_getallocf+20>
=> 0x000071b9f6d3014d <+13>:    mov    0x8(%rax),%rdx
   0x000071b9f6d30151 <+17>:    mov    %rdx,(%rsi)
   0x000071b9f6d30154 <+20>:    mov    (%rax),%rax
   0x000071b9f6d30157 <+23>:    ret
End of assembler dump.
(gdb) i reg
rax            0x3ff0000000000000  4607182418800017408
rbx            0x10                16
rcx            0x5e5a15531644      103740997834308
rdx            0x5e5a15531500      103740997833984
rsi            0x7ffe1d62a320      140729391424288
rdi            0x71b9f53c11e0      125043497243104
rbp            0x1                 0x1
rsp            0x7ffe1d62a298      0x7ffe1d62a298
r8             0x5e5a135c0010      103740964864016
r9             0x7                 7
r10            0x5e5a155603f0      103740998026224
r11            0xbbb33a5e2038b5df  -4921525791843895841
r12            0x5e5a15531650      103740997834320
r13            0xffff0004          4294901764
r14            0x5e5a15531640      103740997834304
r15            0x1                 1
rip            0x71b9f6d3014d      0x71b9f6d3014d <lua_getallocf+13>
eflags         0x10202             [ IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
fs_base        0x71b9f69ce080      125043520364672
gs_base        0x0                 0
(gdb) p g
$5 = (global_State *) 0x3ff0000000000000
(gdb) p *g
Cannot access memory at address 0x3ff0000000000000
(gdb) ptype global_State
type = struct global_State {
    lua_Alloc allocf;
    void *allocd;
    GCState gc;
    GCstr strempty;
    uint8_t stremptyz;
    uint8_t hookmask;
    uint8_t dispatchmode;
    uint8_t vmevmask;
    StrInternState str;
    volatile int32_t vmstate;
    GCRef mainthref;
    SBuf tmpbuf;
    TValue tmptv;
    TValue tmptv2;
    Node nilnode;
    TValue registrytv;
    GCupval uvhead;
    int32_t hookcount;
    int32_t hookcstart;
    lua_Hook hookf;
    lua_CFunction wrapf;
    lua_CFunction panic;
    BCIns bc_cfunc_int;
    BCIns bc_cfunc_ext;
    GCRef cur_L;
    MRef jit_base;
    MRef ctype_state;
    PRNGState prng;
    GCRef gcroot[39];
}
(gdb)

though I'm not sure what is the issue, mov 0x8(%rax),%rdx looks like g->allocd (as allocd's offset in global_State is 8), so the address (global_State *) 0x3ff0000000000000 is invalid? Like not assigned to that process? (I'm not experienced with x86 assembly).

@jedrzejboczar
Copy link
Author

jedrzejboczar commented Nov 12, 2024

Closing as this was solved in mlua-rs/mlua#479.

TLDR: don't use lazy-loading for lua-json5, e.g. with lazy.nvim ensure that it is defined such that require('json5') will be called, e.g.

{
    'Joakker/lua-json5',
    config = function()
        require('json5')
    end
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant