From 60c69b8c29b52a21f9d43450677f3debaf708c28 Mon Sep 17 00:00:00 2001 From: harrand Date: Sun, 6 Aug 2023 00:14:53 +0100 Subject: [PATCH] [lua] added lua::state::collect_stack() which scrapes the lua stack into a pretty-printable string. when a lua assert failure happens, the stack is now printed out to help diagnosis --- src/tz/lua/state.cpp | 37 ++++++++++++++++++++++++++++++++++++- src/tz/lua/state.hpp | 1 + 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/tz/lua/state.cpp b/src/tz/lua/state.cpp index 34dc556e52..eb2ac37ff5 100644 --- a/src/tz/lua/state.cpp +++ b/src/tz/lua/state.cpp @@ -92,6 +92,40 @@ namespace tz::lua return ret; } + std::string state::collect_stack() const + { + if(!this->impl_check_stack(3)) + { + return ""; + } + std::string ret; + + auto* s = static_cast(this->lstate); + int top = lua_gettop(s); + int bottom = 1; + ret = "=== stack (size: " + std::to_string(top - bottom + 1) + ") ===\n"; + lua_getglobal(s, "tostring"); + for(int i = top; i >= bottom; i--) + { + lua_pushvalue(s, -1); + lua_pushvalue(s, i); + lua_pcall(s, 1, 1, 0); + const char* str = lua_tostring(s, -1); + ret += std::string(">") + std::to_string(i) + ": "; + if(str == nullptr) + { + ret += luaL_typename(s, i) + std::string("\n"); + } + else + { + ret += str + std::string("\n"); + } + lua_pop(s, 1); + } + lua_pop(s, 1); + return ret + "=== end ==="; + } + bool state::impl_check_stack(std::size_t sz) const { auto* s = static_cast(this->lstate); @@ -117,10 +151,11 @@ namespace tz::lua int tz_lua_assert(lua_State* state) { bool b = lua_toboolean(state, 1); + std::string stack = lua::state{state}.collect_stack(); lua_Debug ar; lua_getstack(state, 1, &ar); lua_getinfo(state, "nSl", &ar); - tz::assert(b, "Lua Assertion: ```lua\n\n%s\n\n```\nOn line %d", ar.source, ar.currentline); + tz::assert(b, "Lua Assertion Failure: ```lua\n\n%s\n\n```\nOn line %d\nStack:\n%s", ar.source, ar.currentline, stack.c_str()); return 0; } diff --git a/src/tz/lua/state.hpp b/src/tz/lua/state.hpp index f07920a64f..684e7ef07e 100644 --- a/src/tz/lua/state.hpp +++ b/src/tz/lua/state.hpp @@ -42,6 +42,7 @@ namespace tz::lua bool define_int(const char* varname, std::int64_t i) const; bool define_uint(const char* varname, std::uint64_t u) const; bool define_func(const char* varname, void* func_ptr) const; + std::string collect_stack() const; private: bool impl_check_stack(std::size_t sz) const; void* lstate = nullptr;