Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • core/tarantool-module
1 result
Show changes
Commits on Source (4)
  • Dmitry Ivanov's avatar
    fcda5c8b
  • Dmitry Ivanov's avatar
    3eb4793c
  • Dmitry Ivanov's avatar
    fix: lua state trampolines should be "C-unwind", not "C" · 52bb62ca
    Dmitry Ivanov authored
    This is due to the fact that lua_error calls _Unwind_RaiseException
    under the hood, which causes rust's extern "C" functions to misbehave
    when an exception passes through their frame.
    
    Without this change we crash with a following log:
    
    ```
    i1  | 2024-10-09 02:13:28.940 [120075] main/111/main C> panicked at library/core/src/panicking.rs:221:5:
    i1  | panic in a function that cannot unwind
    i1  | 2024-10-09 02:13:28.940 [120075] main/111/main C> backtrace:
    i1  | disabled backtrace
    i1  | 2024-10-09 02:13:28.940 [120075] main/111/main C> aborting due to panic
    i1  | [supervisor:120065] no ipc message from child
    i1  | [supervisor:120065] subprocess 120075 was signaled with SIGABRT
    i1  | [supervisor:120065] core dumped
    ```
    
    picodata repro:
    
    ```shell
    pipenv run pytest -k test_submit_sql_after_revoke
    ```
    
    backtrace:
    
    ```
    #0  0x00007e04dc2a53f4 in ?? () from /usr/lib/libc.so.6
    #1  0x00007e04dc24c120 in raise () from /usr/lib/libc.so.6
    #2  0x00007e04dc2334c3 in abort () from /usr/lib/libc.so.6
    #3  0x0000000005961a6a in std::sys::pal::unix::abort_internal () at library/std/src/sys/pal/unix/mod.rs:370
    #4  0x0000000001e3227a in std::process::abort () at library/std/src/process.rs:2388
    #5  0x0000000002e2d476 in picodata::cli::run::main::{closure#0}::{closure#1} (info=0x7e04bb8800f8) at src/cli/run.rs:120
    #6  0x000000000595691f in alloc::boxed::{impl#50}::call<(&std::panic::PanicHookInfo), (dyn core::ops::function::Fn<(&std::panic::PanicHookInfo), Output=()> + core::marker::Send + core::marker::Sync), alloc::alloc::Global> ()
        at library/alloc/src/boxed.rs:2084
    #7  std::panicking::rust_panic_with_hook () at library/std/src/panicking.rs:808
    #8  0x0000000005956513 in std::panicking::begin_panic_handler::{closure#0} () at library/std/src/panicking.rs:667
    #9  0x0000000005953c99 in std::sys::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::{closure_env#0}, !> () at library/std/src/sys/backtrace.rs:168
    #10 0x00000000059561d4 in std::panicking::begin_panic_handler () at library/std/src/panicking.rs:665
    #11 0x0000000001e34e35 in core::panicking::panic_nounwind_fmt::runtime () at library/core/src/panicking.rs:112
    #12 core::panicking::panic_nounwind_fmt () at library/core/src/panicking.rs:122
    #13 0x0000000001e34ec2 in core::panicking::panic_nounwind () at library/core/src/panicking.rs:221
    #14 0x0000000001e350e6 in core::panicking::panic_cannot_unwind () at library/core/src/panicking.rs:309
    #15 0x0000000002c17f7a in tlua::functions_write::wrapper<tlua::functions_write::Function<picodata::set_login_check::{closure_env#1}, (alloc::string::String, bool, *mut tlua::ffi::lua_State), ()>, (alloc::string::String, bool, *mut tlua::ffi::lua_State), ()> (lua=0x40c2cc90) at tarantool/tlua/src/functions_write.rs:455
    #16 0x000000000321d513 in lj_BC_FUNCC () at buildvm_x86.dasc:811
    #17 0x0000000003224253 in lua_pcall (L=L@entry=0x40c2cc90, nargs=<optimized out>, nresults=nresults@entry=-1, errfunc=errfunc@entry=0) at picodata/tarantool-sys/third_party/luajit/src/lj_api.c:1172
    #18 0x000000000301b47b in luaT_call (L=L@entry=0x40c2cc90, nargs=<optimized out>, nreturns=nreturns@entry=-1) at picodata/tarantool-sys/src/lua/utils.c:619
    ```
    52bb62ca
  • Dmitry Ivanov's avatar
    chore: update the changelog · dff8aba8
    Dmitry Ivanov authored
    dff8aba8
......@@ -28,7 +28,7 @@ variables:
KANIKO_REGISTRY_MIRROR: docker-proxy.binary.picodata.io
CACHE_PATHS: target
CARGO_INCREMENTAL: 0
RUST_VERSION: "1.70" # Note: without the quotes yaml thinks this is a float and removes the trailing 0
RUST_VERSION: "1.71" # Note: without the quotes yaml thinks this is a float and removes the trailing 0
CARGO_HOME: /shared-storage/tarantool-module/.cargo
BASE_IMAGE_VANILLA: docker-public.binary.picodata.io/tarantool-module-build-base-vanilla
BASE_IMAGE_FORK: docker-public.binary.picodata.io/tarantool-module-build-base-fork
......
......@@ -35,6 +35,9 @@ restricting time connection establishment.
### Breaking changes
- Replace `network::protocol::codec::{encode_header, decode_header}` functions
with `network::protocol::codec::Header::{encode, decode}` methods.
- Use `extern "C-unwind"` instead of `extern "C"` for all trampolines which take `*mut ffi::lua_State`
(checked with `rg 'extern "C".*lua_State'`). `tlua::error!` throws an exception to unwind the stack,
hence we need to use a proper ABI to fix UB in picodata.
### Added (picodata)
......
......@@ -50,7 +50,7 @@ mod msgpack {
pub tarantool: Option<String>,
/// Allows optional fields of unnamed structs to be decoded if values are not presented.
pub allow_array_optionals: bool,
/// https://serde.rs/enum-representations.html#untagged
/// <https://serde.rs/enum-representations.html#untagged>
pub untagged: bool,
}
......
......@@ -15,7 +15,7 @@ documentation = "https://docs.rs/tarantool/"
repository = "https://github.com/picodata/tarantool-module"
keywords = ["ffi", "database", "tarantool"]
categories = ["database"]
rust-version = "1.70"
rust-version = "1.71"
[dependencies]
base64 = "0.13"
......
......@@ -895,7 +895,7 @@ where
}
}
unsafe extern "C" fn trampoline_for_lua(l: *mut lua::lua_State) -> i32 {
unsafe extern "C-unwind" fn trampoline_for_lua(l: *mut lua::lua_State) -> i32 {
let ud_ptr = lua::lua_touserdata(l, lua::lua_upvalueindex(1));
let f = (ud_ptr as *mut Option<F>)
......@@ -1014,7 +1014,7 @@ mod impl_details {
/// A callback for the "__gc" event. It checks if the value was moved out
/// and if not it drops the value.
unsafe extern "C" fn wrap_gc<T>(lua: *mut ffi::lua_State) -> i32 {
unsafe extern "C-unwind" fn wrap_gc<T>(lua: *mut ffi::lua_State) -> i32 {
let ud_ptr = ffi::lua_touserdata(lua, 1);
let ud = ud_ptr
.cast::<UDBox<T>>()
......
......@@ -109,7 +109,7 @@ pub type lua_Integer = libc::ptrdiff_t;
/// return 2; /* number of results */
/// }
/// ```
pub type lua_CFunction = unsafe extern "C" fn(l: *mut lua_State) -> c_int;
pub type lua_CFunction = unsafe extern "C-unwind" fn(l: *mut lua_State) -> c_int;
pub type lua_Alloc = extern "C" fn(
ud: *mut libc::c_void,
......
......@@ -245,7 +245,7 @@ macro_rules! impl_function_ext {
ffi::lua_pushcclosure(lua.as_lua(), wrapper::<Self, _, R>, 1);
return Ok(PushGuard::new(lua, 1));
extern "C" fn wrap_gc<T>(lua: LuaState) -> i32 {
extern "C-unwind" fn wrap_gc<T>(lua: LuaState) -> i32 {
unsafe {
let obj = ffi::lua_touserdata(lua, -1);
ptr::drop_in_place(obj.cast::<T>());
......@@ -313,7 +313,7 @@ impl_function_ext! {A B C D E F G H I J K M N}
/// use tlua::{Lua, CFunction, LuaState, ffi};
///
/// let lua = Lua::new();
/// unsafe extern "C" fn return_42(lua: LuaState) -> libc::c_int {
/// unsafe extern "C-unwind" fn return_42(lua: LuaState) -> libc::c_int {
/// ffi::lua_pushinteger(lua, 42);
/// 1
/// }
......@@ -452,7 +452,7 @@ where
}
// this function is called when Lua wants to call one of our functions
extern "C" fn wrapper<T, A, R>(lua: LuaState) -> libc::c_int
extern "C-unwind" fn wrapper<T, A, R>(lua: LuaState) -> libc::c_int
where
T: FnMutExt<A, Output = R>,
// TODO(gmoshkin): these bounds are too strict, how do we loosen them?
......@@ -525,7 +525,7 @@ where
out: Option<R>,
}
unsafe extern "C" fn trampoline<F, R>(l: LuaState) -> i32
unsafe extern "C-unwind" fn trampoline<F, R>(l: LuaState) -> i32
where
F: FnOnce(StaticLua) -> R,
{
......@@ -550,7 +550,7 @@ mod tests {
fn c_function() {
let lua = crate::Lua::new();
unsafe extern "C" fn return_42(lua: crate::LuaState) -> libc::c_int {
unsafe extern "C-unwind" fn return_42(lua: crate::LuaState) -> libc::c_int {
ffi::lua_pushinteger(lua, 42);
1
}
......
......@@ -989,7 +989,7 @@ impl TempLua {
}
// called whenever lua encounters an unexpected error.
extern "C" fn panic(lua: *mut ffi::lua_State) -> libc::c_int {
extern "C-unwind" fn panic(lua: *mut ffi::lua_State) -> libc::c_int {
let err = unsafe { ffi::lua_tostring(lua, -1) };
let err = unsafe { CStr::from_ptr(err) };
let err = String::from_utf8(err.to_bytes().to_vec()).unwrap();
......
......@@ -42,7 +42,7 @@ where
/// A callback for the "__gc" event. It checks if the value was moved out
/// and if not it drops the value.
unsafe extern "C" fn wrap_gc<T>(lua: *mut ffi::lua_State) -> i32 {
unsafe extern "C-unwind" fn wrap_gc<T>(lua: *mut ffi::lua_State) -> i32 {
let ud_ptr = ffi::lua_touserdata(lua, 1);
let ud = ud_ptr
.cast::<UDBox<T>>()
......@@ -56,7 +56,7 @@ where
// Called when an object inside Lua is being dropped.
#[inline]
extern "C" fn destructor_wrapper<T>(lua: *mut ffi::lua_State) -> libc::c_int {
extern "C-unwind" fn destructor_wrapper<T>(lua: *mut ffi::lua_State) -> libc::c_int {
unsafe {
let obj = ffi::lua_touserdata(lua, -1);
ptr::drop_in_place(obj as *mut TypeId);
......