summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2017-06-09 12:16:31 +0200
committerLukas Pioch <lukas@zgow.de>2017-06-09 12:16:31 +0200
commit3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6 (patch)
tree51b2547f57ffda8523432cacf10788cedbef352f
parentFixes problems with windows: (diff)
downloadcuberite-3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6.tar
cuberite-3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6.tar.gz
cuberite-3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6.tar.bz2
cuberite-3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6.tar.lz
cuberite-3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6.tar.xz
cuberite-3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6.tar.zst
cuberite-3c4e443ddc211b4ecdd2b990a3fa9b12b46efaf6.zip
-rw-r--r--Server/Plugins/Debuggers/Debuggers.lua12
-rw-r--r--Server/Plugins/Debuggers/Info.lua6
-rw-r--r--src/Bindings/LuaState.cpp8
-rw-r--r--src/Bindings/LuaState.h37
4 files changed, 60 insertions, 3 deletions
diff --git a/Server/Plugins/Debuggers/Debuggers.lua b/Server/Plugins/Debuggers/Debuggers.lua
index 6c47a8a17..0965a17c2 100644
--- a/Server/Plugins/Debuggers/Debuggers.lua
+++ b/Server/Plugins/Debuggers/Debuggers.lua
@@ -2279,6 +2279,18 @@ end
+function HandleConsoleTestErr(a_Split, a_EntireCmd)
+ cRoot:Get():GetDefaultWorld():ForEachEntity(
+ function (a_CBEntity)
+ error("This error should not abort the server")
+ end
+ )
+end
+
+
+
+
+
function HandleConsoleTestJson(a_Split, a_EntireCmd)
LOG("Testing Json parsing...")
local t1 = cJson:Parse([[{"a": 1, "b": "2", "c": [3, "4", 5], "d": true }]])
diff --git a/Server/Plugins/Debuggers/Info.lua b/Server/Plugins/Debuggers/Info.lua
index e3b0beee1..b9eb0eeda 100644
--- a/Server/Plugins/Debuggers/Info.lua
+++ b/Server/Plugins/Debuggers/Info.lua
@@ -350,6 +350,12 @@ g_PluginInfo =
HelpString = "Tests inter-plugin calls with various values"
},
+ ["testerr"] =
+ {
+ Handler = HandleConsoleTestErr,
+ HelpString = "Tests the server's ability to recover from errors in callbacks (GH #3733)",
+ },
+
["testjson"] =
{
Handler = HandleConsoleTestJson,
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index ca0a258d9..947e337fc 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -1454,8 +1454,12 @@ bool cLuaState::CallFunction(int a_NumResults)
LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), CurrentFunctionName.c_str());
// Remove the error handler and error message from the stack:
- ASSERT(lua_gettop(m_LuaState) == 2);
- lua_pop(m_LuaState, 2);
+ auto top = lua_gettop(m_LuaState);
+ if (top < 2)
+ {
+ LogStackValues(Printf("The Lua stack is in an unexpected state, expected at least two values there, but got %d", top).c_str());
+ }
+ lua_pop(m_LuaState, std::min(2, top));
return false;
}
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index ac911557d..9cbfbf69d 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -105,6 +105,41 @@ public:
#define ASSERT_LUA_STACK_BALANCE(...)
#endif
+
+ /** Makes sure that the Lua state's stack has the same number of elements on destruction as it had on construction of this object (RAII).
+ Can only remove elements, if there are less than expected, throws. */
+ class cStackBalancePopper
+ {
+ public:
+ cStackBalancePopper(cLuaState & a_LuaState):
+ m_LuaState(a_LuaState),
+ m_Count(lua_gettop(a_LuaState))
+ {
+ }
+
+ ~cStackBalancePopper()
+ {
+ auto curTop = lua_gettop(m_LuaState);
+ if (curTop > m_Count)
+ {
+ // There are some leftover elements, adjust the stack:
+ m_LuaState.LogStackValues(Printf("Re-balancing Lua stack, expected %d values, got %d:", m_Count, curTop).c_str());
+ lua_pop(m_LuaState, curTop - m_Count);
+ }
+ else if (curTop < m_Count)
+ {
+ // This is an irrecoverable error, rather than letting the Lua engine crash undefinedly later on, abort now:
+ LOGERROR("Unable to re-balance Lua stack, there are elements missing. Expected at least %d elements, got %d.", m_Count, curTop);
+ throw std::runtime_error(Printf("Unable to re-balance Lua stack, there are elements missing. Expected at least %d elements, got %d.", m_Count, curTop));
+ }
+ }
+
+ protected:
+ cLuaState & m_LuaState;
+ int m_Count;
+ };
+
+
/** Provides a RAII-style locking for the LuaState.
Used mainly by the cPluginLua internals to provide the actual locking for interface operations, such as callbacks. */
class cLock
@@ -704,7 +739,7 @@ public:
template <typename FnT, typename... Args>
bool Call(const FnT & a_Function, Args &&... args)
{
- ASSERT_LUA_STACK_BALANCE(m_LuaState);
+ cStackBalancePopper balancer(*this);
m_NumCurrentFunctionArgs = -1;
if (!PushFunction(std::forward<const FnT &>(a_Function)))
{