From ccf4ac6b44a378d8f0e32b8186fdc4d3b25c3bda Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 25 Jul 2025 12:48:27 +0200 Subject: Fix crashes in MSVC release builds related to KeeperOperationInProgress * scope the KeeperOperationInProgress object on linda calls * but since it's not enough, just comment it, it is only debug stuff anyway --- src/lanes.cpp | 6 +++++- src/linda.cpp | 28 +++++++++++++++++----------- src/linda.hpp | 4 ++-- 3 files changed, 24 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lanes.cpp b/src/lanes.cpp index d9ac4df..4373aee 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -178,9 +178,13 @@ LUAG_FUNC(sleep) } else if (lua_isnoneornil(L_, 1)) { lua_pushnumber(L_, 0); // L_: duration? receive() timerLinda 0 } else if (!lua_isnumber(L_, 1)) { - raise_luaL_argerror(L_, StackIndex{ 1 }, "invalid duration"); + raise_luaL_argerror(L_, StackIndex{ 1 }, "duration must be a number"); } else { + auto const _n{ lua_tonumber(L_, 1) }; + if (_n < 0) { + raise_luaL_argerror(L_, StackIndex{ 1 }, "duration must be >= 0"); + } lua_pushnumber(L_, lua_tonumber(L_, 1)); // L_: duration? receive() timerLinda duration } luaW_pushstring(L_, "ac100de1-a696-4619-b2f0-a26de9d58ab8"); // L_: duration? receive() timerLinda duration key diff --git a/src/linda.cpp b/src/linda.cpp index 75d1748..56285f7 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -422,17 +422,23 @@ int Linda::ProtectedCall(lua_State* const L_, lua_CFunction const f_) // doing LindaFactory::deleteDeepObjectInternal -> keeper_call(clear) lua_gc(L_, LUA_GCSTOP, 0); - LUA_ASSERT_CODE(auto const _koip{ _linda->startKeeperOperation(L_) }); - // if we didn't do anything wrong, the keeper stack should be clean - LUA_ASSERT(L_, lua_gettop(_K) == 0); - - // push the function to be called and move it before the arguments - lua_pushcfunction(L_, f_); - lua_insert(L_, 1); - // do a protected call - LuaError const _rc{ lua_pcall(L_, lua_gettop(L_) - 1, LUA_MULTRET, 0) }; - // whatever happens, the keeper state stack must be empty when we are done - lua_settop(_K, 0); + LuaError _rc{}; + { + // there is something really strange here: in Release builds, MSVC will invoke _koip destructor on stack unwinding when we raise_lua_error() below + // even though the variable does not exist in the stack frame because it went out of scope -> comment until we understand why, because it causes a crash + //LUA_ASSERT_CODE(auto const _koip{ _linda->startKeeperOperation(L_) }); + + // if we didn't do anything wrong, the keeper stack should be clean + LUA_ASSERT(L_, lua_gettop(_K) == 0); + + // push the function to be called and move it before the arguments + lua_pushcfunction(L_, f_); + lua_insert(L_, 1); + // do a protected call + _rc = ToLuaError(lua_pcall(L_, lua_gettop(L_) - 1, LUA_MULTRET, 0)); + // whatever happens, the keeper state stack must be empty when we are done + lua_settop(_K, 0); + } // restore normal GC operations lua_gc(L_, LUA_GCRESTART, 0); diff --git a/src/linda.hpp b/src/linda.hpp index cff30e5..9288b38 100644 --- a/src/linda.hpp +++ b/src/linda.hpp @@ -21,7 +21,7 @@ class Linda final lua_State* const L{}; // just here for inspection while debugging public: - KeeperOperationInProgress(Linda& linda_, lua_State* const L_) + KeeperOperationInProgress(Linda& linda_, lua_State* const L_) noexcept : linda{ linda_ } , L{ L_ } { @@ -29,7 +29,7 @@ class Linda final } public: - ~KeeperOperationInProgress() + ~KeeperOperationInProgress() noexcept { [[maybe_unused]] UnusedInt const _prev{ linda.keeperOperationCount.fetch_sub(1, std::memory_order_seq_cst) }; } -- cgit v1.2.3-55-g6feb