mlua-rs/rlua

Undefined symbol lua_checkstack

xhyrom opened this issue · 8 comments

Hello, i'm trying to load cjson module with this configuration:

            Lua::unsafe_new_with_flags(
                StdLib::ALL_NO_DEBUG, // Load all Lua standard libraries apart from debug
                InitFlags::DEFAULT - InitFlags::REMOVE_LOADLIB, // Allow loading binary libraries
            )

and code:

local cjson = require "cjson"

local json = cjson.encode({
    foo = "bar",
    some_object = {},
    some_array = cjson.empty_array
})

but i got

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: RuntimeError("error loading module 'cjson' from file '/usr/local/lib/lua/5.4/cjson.so':\n\t/usr/local/lib/lua/5.4/cjson.so: undefined symbol: lua_checkstack\nstack traceback:\n\t[C]: in ?\n\t[C]: in ?\n\t[C]: in function 'require'\n\t[string \"?\"]:1: in main chunk")', cli/src/main.rs:13:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

with normal lua, it works great

version: 0.19.5

I think the problem (similar to #264) is that we're not exporting the lua symbols. A workaround may be using the system-lua54 feature (and disabling default features), which would use a Lua library installed on your system instead of compiling one in.

I need to work out the linker options to export the Lua symbols to get it to work with the builtin Lua.

Having done some investigation, I think the fix is to the end application.

The ideal fix would be the export-executable-symbols, which is available on nightly but not yet on stable - so if you're using nightly, passing -Z export-executable-symbols to cargo should make it work.

Until that's available, you can do it by adding linker flags. If I add println!("cargo:rustc-link-arg-examples=-Wl,-export-dynamic"); to rlua's build.rs, then for example target/debug/examples/repl has Lua (and other) symbols exported. For an end executable, you'd use rustc-link-arg-bins or similar. Unfortunately the specific linker option needed may vary for different platforms (this was on Linux).

Thanks, i'll use nightly version for now 😅

I, too, am working through this issue. Had used -export_dynamic (MacOS is oh so slightly difficult different...) which does include some of the required symbols but I'm still missing luaL_openlibs. I'm attempting to use this with http Lua library.

For completeness sake w/o exporting dynamic it is failing earlier:

runtime error: error loading module 'lpeg' from file '/opt/homebrew/lib/lua/5.4/lpeg.so':
        dlopen(/opt/homebrew/lib/lua/5.4/lpeg.so, 0x0006): symbol not found in flat namespace '_lua_settable'

With exporting dynamic:

runtime error: error loading module '_cqueues' from file '/opt/homebrew/lib/lua/5.4/_cqueues.so':
        dlopen(/opt/homebrew/lib/lua/5.4/_cqueues.so, 0x0006): symbol not found in flat namespace '_luaL_openlibs'

Since luaL_openlibs is made available through the rlua-lua54-sys crate I thought linking on the Rust side with -C link-dead-code would fix this but it didn't.

$ nm ./target/debug/rtest | rg luaL_openlibs

$

I'm still working through this, but adding my findings as well to this issue if someone had a quick fix.

This is working fine w/ system Lua so it's not a blocker but would be nice to use the embedded Lua.

devzf commented

I would recommend switching to mlua. it doesn't have those problems.
rlua unfortunaly is dead.

@bigmstone Thanks for reporting your findings!
It may be that rlua needs to include references to functions it doesn't otherwise use (maybe especially in C source files that aren't otherwise referenced) for this case.

@devzf i dont think rlua is dead, @jugglerchris do a great job here

khvzak commented

rlua is going to be deprecated soon in favour of mlua. See https://github.com/mlua-rs/mlua/blob/master/FAQ.md#loading-a-c-module-fails-with-error-undefined-symbol-lua_xxx-how-to-fix about about undefined symbols error.