Skip to content

Crash on macos/x64 when integrated with Rust #1099

@khvzak

Description

@khvzak

Sorry if this issue is irrelevant to LuaJIT and related to changes/bugs in rust compiler instead.
I'm maintainer of mlua and when checked the latest luajit and rustc compiler noticed that some tests on macos do not pass (crash).

I nailed the problem down to the following example:

use std::ffi::{c_char, c_void};

extern "C" {
    fn luaL_newstate() -> *mut c_void;
    fn luaL_loadstring(state: *mut c_void, s: *const c_char) -> i32;
    fn lua_close(state: *mut c_void);
    fn lua_pcall(state: *mut c_void, nargs: i32, nresults: i32, errfunc: i32) -> i32;
}

fn main() {
    unsafe {
        thread_local! {
            static TL_VAR: i32 = 0;
        }

        // Not crashing if we don't use the thread local variable
        TL_VAR.with(|_| {});

        let state = luaL_newstate();
        luaL_loadstring(state, b"error('hello')\0".as_ptr() as _);
        let ret = lua_pcall(state, 0, 0, 0);
        println!("ret = {ret}");
        lua_close(state);
    }
}

#[cfg(test)]
#[test]
fn test() {
    main();
}

It crashed when running on macOS using cargo test (cargo run works).

lldb says it crashes inside LuaJIT in next place:

running 1 test
Process 70345 stopped
* thread #2, name = 'test', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x000000010000a24f luajit_crash-e60e73163c2df13f`lj_err_throw [inlined] err_raise_ext(g=0x00000001003423e0, errcode=2) at lj_err.c:761:3 [opt]
   758 	/* Raise external exception. */
   759 	static void err_raise_ext(global_State *g, int errcode)
   760 	{
-> 761 	  memset(&static_uex, 0, sizeof(static_uex));
   762 	  static_uex.ex.exclass = LJ_UEXCLASS_MAKE(errcode);
   763 	  static_uex.g = g;
   764 	  _Unwind_RaiseException(&static_uex.ex);
Target 0: (luajit_crash-e60e73163c2df13f) stopped.
warning: luajit_crash-e60e73163c2df13f was compiled with optimization - stepping may behave oddly; variables may not be available.

When LuaJIT is compiled without -O2 if crashes in another place:

Process 72676 stopped
* thread #2, name = 'test', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x00007ff81d48b747 libunwind.dylib`_Unwind_RaiseException + 39
libunwind.dylib`:
->  0x7ff81d48b747 <+39>: movaps %xmm0, 0x10(%r14)
    0x7ff81d48b74c <+44>: leaq   0x346a9d05(%rip), %rax    ; vtable for libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_x86_64> + 16
    0x7ff81d48b753 <+51>: movq   %rax, -0x600(%rbp)
    0x7ff81d48b75a <+58>: leaq   0x363b8e7f(%rip), %rax    ; libunwind::LocalAddressSpace::sThisAddressSpace
Target 0: (luajit_crash-e60e73163c2df13f) stopped.
(lldb) bt
* thread #2, name = 'test', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x00007ff81d48b747 libunwind.dylib`_Unwind_RaiseException + 39
    frame #1: 0x000000010000d7a6 luajit_crash-e60e73163c2df13f`err_raise_ext(g=0x00000001002943e0, errcode=2) at lj_err.c:764:3
    frame #2: 0x000000010000d703 luajit_crash-e60e73163c2df13f`lj_err_throw(L=0x0000000100294380, errcode=2) at lj_err.c:780:3
    frame #3: 0x000000010000dc07 luajit_crash-e60e73163c2df13f`lj_err_run(L=0x0000000100294380) at lj_err.c:896:3
...

It does not crash when remove TL_VAR.with(|_| {}); code.

macOS 13.5.2 (x86_64)
Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: x86_64-apple-darwin22.6.0
rustc 1.72.1 (d5c2e9c34 2023-09-13)
LuaJIT commit becf5cc (latest master)
compiled with: BUILDMODE=static MACOSX_DEPLOYMENT_TARGET="13.0" "make" "-e"

I made a repo to reproduce: https://github.com/khvzak/luajit_crash
It requires libluajit.a in the project root, and can be run by cargo test

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions