From 93b02a6fad3ddb35336b63502ad62a0c6eb1ba60 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 18 Nov 2013 06:49:51 -0800 Subject: [PATCH] fix(lua): fix C++ stack unwinding bug, we should never invoke lua_error from a catch block lua_error and luaL_error are based on the longjmp C function. They will not correctly unwind the C++ stack. We should only invoke them after we finished handling the C++ exceptions and unwinding the C++ stack, and invoking the destructors for each object living on the stack. Signed-off-by: Leonardo de Moura --- src/bindings/lua/util.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/bindings/lua/util.cpp b/src/bindings/lua/util.cpp index 3316f2c1d..5ea042303 100644 --- a/src/bindings/lua/util.cpp +++ b/src/bindings/lua/util.cpp @@ -105,32 +105,25 @@ void pcall(lua_State * L, int nargs, int nresults, int errorfun) { throw lua_exception(lua_tostring(L, -1)); } -static thread_local std::string g_error_msg; - int safe_function_wrapper(lua_State * L, lua_CFunction f){ - char const * error_msg; try { return f(L); } catch (kernel_exception & e) { std::ostringstream out; options o = get_global_options(L); out << mk_pair(e.pp(get_global_formatter(L), o), o); - g_error_msg = out.str(); - error_msg = g_error_msg.c_str(); + lua_pushstring(L, out.str().c_str()); } catch (elaborator_exception & e) { push_justification(L, e.get_justification()); - return lua_error(L); } catch (exception & e) { - g_error_msg = e.what(); - error_msg = g_error_msg.c_str(); + lua_pushstring(L, e.what()); } catch (std::bad_alloc &) { - error_msg = "out of memory"; + lua_pushstring(L, "out of memory"); } catch (std::exception & e) { - g_error_msg = e.what(); - error_msg = g_error_msg.c_str(); + lua_pushstring(L, e.what()); } catch(...) { - throw; + lua_pushstring(L, "unknown error"); } - return luaL_error(L, error_msg); + return lua_error(L); } }