[MacPorts] #68126: neovim @0.9.1_1: segmentation fault
MacPorts
noreply at macports.org
Sat Dec 16 23:18:53 UTC 2023
#68126: neovim @0.9.1_1: segmentation fault
--------------------------------+----------------------------
Reporter: dlamija | Owner: raimue
Type: defect | Status: assigned
Priority: Normal | Milestone:
Component: ports | Version: 2.8.1
Resolution: | Keywords: ventura sonoma
Port: neovim luv-luajit |
--------------------------------+----------------------------
Comment (by echesakov):
I think the issue is due to two conflicting definitions of macro
`LUA_REGISTRYINDEX` used by `luv-luajit` and `luajit` ports.
The macro definition seems to change between 5.1 and 5.3 versions of Lua
language:
{{{
find /opt/local/include -name 'lua\.h' | xargs grep 'define
LUA_REGISTRYINDEX'
/opt/local/include/lua5.1/lua.h:#define LUA_REGISTRYINDEX (-10000)
/opt/local/include/luajit-2.1/lua.h:#define LUA_REGISTRYINDEX (-10000)
/opt/local/include/lua5.3/lua.h:#define LUA_REGISTRYINDEX
(-LUAI_MAXSTACK - 1000)
/opt/local/include/lua.h:#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK -
1000)
}}}
When port `luv-luajit` and, file `luv.c` in particular, is compiled it
picks up the definition from `/opt/local/include/lua.h` (provided by port
`lua`).
Note `-I/opt/local/include` used in the following command line:
{{{
[ 50%] Building C object CMakeFiles/libluv.dir/src/luv.c.o
/usr/bin/clang -Dlibluv_EXPORTS -I/opt/local/include
-I/opt/local/include/luajit-2.1
-I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_devel_luv
/luv-luajit/work/luv-1.45.0-0/deps/lua-compat-5.3/c-api -pipe -Os -DNDEBUG
-I/opt/local/include
-isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -arch arm64
-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -mmacosx-
version-min=14.0 -fPIC -MD -MT CMakeFiles/libluv.dir/src/luv.c.o -MF
CMakeFiles/libluv.dir/src/luv.c.o.d -o CMakeFiles/libluv.dir/src/luv.c.o
-c
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_devel_luv
/luv-luajit/work/luv-1.45.0-0/src/luv.c
}}}
By running preprocessor on `luv.c` and peeking at the definition of
`luv_context` function:
{{{
cd
"/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_devel_luv
/luv-luajit/work/build"
/usr/bin/clang -Dlibluv_EXPORTS -I/opt/local/include
-I/opt/local/include/luajit-2.1
-I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_devel_luv
/luv-luajit/work/luv-1.45.0-0/deps/lua-compat-5.3/c-api -pipe -Os -DNDEBUG
-I/opt/local/include
-isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -arch arm64
-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -mmacosx-
version-min=14.0 -fPIC -MD -MT CMakeFiles/libluv.dir/src/luv.c.o -MF
CMakeFiles/libluv.dir/src/luv.c.o.d -o - -c
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_devel_luv
/luv-luajit/work/luv-1.45.0-0/src/luv.c -E | awk '/extern luv_ctx_t\*
luv_context\(lua_State\* L\) {/','/lua_type/'
extern luv_ctx_t* luv_context(lua_State* L) {
luv_ctx_t* ctx;
lua_pushstring(L, luv_ctx_key);
lua_rawget(L, (-1000000 - 1000));
if ((lua_type(L, (-1)) == 0)) {
}}}
it can be seen that the macro expands to `(-1000000 - 1000)`.
However, port `luajit` (that provides `libluajit-5.1.2.dylib`) and
`ljamalg.c` are compiled against its own version of `lua.h`.
By running preprocessor on `ljamalg.c` and peeking at the definition of
`index2adr` function (when the segmentation fault occurs):
{{{
cd
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_luajit/luajit/work
/LuaJIT-43d0a19158ceabaa51b0462c1ebc97612b420a2e/src
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_luajit/luajit/work/compwrap/cc/usr/bin/clang
-O2 -fomit-frame-pointer -Wall -Os -DLUAJIT_ENABLE_LUA52COMPAT
-isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -arch arm64
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE
-DLUA_ROOT=\"/opt/local\" -DLUA_MULTILIB=\"lib\" -fno-stack-protector
-DLUAJIT_UNWIND_EXTERNAL -E -o - ljamalg.c | awk '/static TValue
\*index2adr\(/,/} else {/'
static TValue *index2adr(lua_State *L, int idx)
{
if (idx > 0) {
TValue *o = L->base + (idx - 1);
return o < L->top ? o : (&(((global_State *)(void
*)(L->glref).ptr64))->nilnode.val);
} else if (idx > (-10000)) {
((void)L);
return L->top + idx;
} else if (idx == (-10002)) {
TValue *o = &(((global_State *)(void *)(L->glref).ptr64))->tmptv;
settabV(L, o, ((GCtab *)((GCobj *)((L->env)).gcptr64)));
return o;
} else if (idx == (-10000)) {
return (&(((global_State *)(void *)(L->glref).ptr64))->registrytv);
} else
}}}
it can be seen that the macro expands to `(-10000)`.
The segmentation fault occurs
{{{
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=1, address=0x800000000027)
* frame #0: 0x0000000100c9db38
libluajit-5.1.2.dylib`___lldb_unnamed_symbol507 + 48
frame #1: 0x0000000100ca5ce8 libluajit-5.1.2.dylib`lua_rawget + 40
frame #2: 0x00000001009ac364 libluv.1.dylib`luv_context + 44
frame #3: 0x00000001009ac42c libluv.1.dylib`luv_set_loop + 24
frame #4: 0x00000001001c33a0
nvim`nlua_common_vim_init.llvm.13061164706051272520 + 572
frame #5: 0x00000001001c2188 nvim`nlua_init + 528
frame #6: 0x00000001001ccda8 nvim`main + 5024
frame #7: 0x00000001889150e0 dyld`start + 2360
}}}
due to this mismatch since when executing `index2adr`
(`___lldb_unnamed_symbol507` in `bt` output) instead of taking `else if
(idx == LUA_REGISTRYINDEX)` branch the code path go to the `else` branch:
{{{
static TValue *index2adr(lua_State *L, int idx)
{
if (idx > 0) {
TValue *o = L->base + (idx - 1);
return o < L->top ? o : niltv(L);
} else if (idx > LUA_REGISTRYINDEX) {
lj_checkapi(idx != 0 && -idx <= L->top - L->base,
"bad stack slot %d", idx);
return L->top + idx;
} else if (idx == LUA_GLOBALSINDEX) {
TValue *o = &G(L)->tmptv;
settabV(L, o, tabref(L->env));
return o;
} else if (idx == LUA_REGISTRYINDEX) {
return registry(L);
} else {
GCfunc *fn = curr_func(L);
lj_checkapi(fn->c.gct == ~LJ_TFUNC && !isluafunc(fn),
"calling frame is not a C function");
if (idx == LUA_ENVIRONINDEX) {
TValue *o = &G(L)->tmptv;
settabV(L, o, tabref(fn->c.env));
return o;
} else {
idx = LUA_GLOBALSINDEX - idx;
return idx <= fn->c.nupvalues ? &fn->c.upvalue[idx-1] : niltv(L);
}
}
}
}}}
By uninstalling `lua` port (need to be forced since `lua-luarocks` still
depends on `lua`) and re-installing `luv-luajit` port I could make the
installation of `neovim` succeed.
While looking into this, I also noticed that `lua51-lpeg` pulls down both
`lua51` and `lua-luarocks` (which in turns pulls down `lua`) and I am not
sure if this looks right:
{{{
port rdeps lua51-lpeg
The following ports are dependencies of lua51-lpeg @1.1.0_0:
lua-luarocks
lua
readline
ncurses
lua53-luarocks
lua53
lua51
}}}
Uninstalling `lua` is, obviously, not a proper solution here but I wanted
to share this in case someone more familiar with MacPorts dependencies
would able to pick it up from here.
--
Ticket URL: <https://trac.macports.org/ticket/68126#comment:34>
MacPorts <https://www.macports.org/>
Ports system for macOS
More information about the macports-tickets
mailing list