From c44ac8ec6e42f21c25d5666fc1fcf936e7748d42 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 17 Oct 2015 21:18:04 -0400 Subject: [PATCH] Improve handling of fatal errors and errors in dfhack.lua * Several fatal errors that occurred during core initialization didn't stop initialization or set 'errorstate' properly, which caused update hooks and other code to crash later. This has been fixed and should address crashes like the one mentioned in #470. * Errors when loading dfhack.lua now cause Lua::Open() to fail, which triggers a fatal error in Core::Init() * Failure to initialize the console no longer results in a call to fatal() (since it didn't actually stop initialization previously) --- library/Core.cpp | 22 +++++++++++++++------- library/LuaTools.cpp | 16 +++++++++++----- library/include/Core.h | 2 +- library/include/LuaTools.h | 2 +- plugins/dwarfmonitor.cpp | 2 ++ 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/library/Core.cpp b/library/Core.cpp index 823c68a59..6fdf65a09 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1336,15 +1336,19 @@ Core::Core() script_path_mutex = new mutex(); }; -void Core::fatal (std::string output, bool deactivate) +void Core::fatal (std::string output) { + errorstate = true; stringstream out; out << output ; - if(deactivate) - out << "DFHack will now deactivate.\n"; + if (output[output.size() - 1] != '\n') + out << '\n'; + out << "DFHack will now deactivate.\n"; if(con.isInited()) { con.printerr("%s", out.str().c_str()); + con.reset_color(); + con.print("\n"); } fprintf(stderr, "%s\n", out.str().c_str()); #ifndef LINUX_BUILD @@ -1395,7 +1399,7 @@ bool Core::Init() delete vif; vif = NULL; errorstate = true; - fatal(out.str(), true); + fatal(out.str()); return false; } p = new DFHack::Process(vif); @@ -1403,7 +1407,7 @@ bool Core::Init() if(!vinfo || !p->isIdentified()) { - fatal ("Not a known DF version.\n", true); + fatal("Not a known DF version.\n"); errorstate = true; delete p; p = NULL; @@ -1429,7 +1433,7 @@ bool Core::Init() else if(con.init(false)) cerr << "Console is running.\n"; else - fatal ("Console has failed to initialize!\n", false); + cerr << "Console has failed to initialize!\n"; /* // dump offsets to a file std::ofstream dump("offsets.log"); @@ -1476,7 +1480,11 @@ bool Core::Init() } // initialize common lua context - Lua::Core::Init(con); + if (!Lua::Core::Init(con)) + { + fatal("Lua failed to initialize"); + return false; + } // create mutex for syncing with interactive tasks misc_data_mutex=new mutex(); diff --git a/library/LuaTools.cpp b/library/LuaTools.cpp index 7992373a9..008cb00c2 100644 --- a/library/LuaTools.cpp +++ b/library/LuaTools.cpp @@ -1701,7 +1701,11 @@ lua_State *DFHack::Lua::Open(color_ostream &out, lua_State *state) Lua::Core::InitCoreContext(); // load dfhack.lua - Require(out, state, "dfhack"); + if (!Require(out, state, "dfhack")) + { + out.printerr("Could not load dfhack.lua\n"); + return NULL; + } lua_settop(state, 0); if (!lua_checkstack(state, 64)) @@ -1868,15 +1872,17 @@ void DFHack::Lua::Core::onUpdate(color_ostream &out) run_timers(out, State, tick_timers, frame[1], world->frame_counter); } -void DFHack::Lua::Core::Init(color_ostream &out) +bool DFHack::Lua::Core::Init(color_ostream &out) { - if (State) - return; + if (State) { + out.printerr("state already exists\n"); + return false; + } State = luaL_newstate(); // Calls InitCoreContext after checking IsCoreContext - Lua::Open(out, State); + return (Lua::Open(out, State) != NULL); } static void Lua::Core::InitCoreContext() diff --git a/library/include/Core.h b/library/include/Core.h index 2d74405e1..f76ba2b73 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -217,7 +217,7 @@ namespace DFHack void operator=(Core const&); // Don't implement // report error to user while failing - void fatal (std::string output, bool will_deactivate); + void fatal (std::string output); // 1 = fatal failure bool errorstate; diff --git a/library/include/LuaTools.h b/library/include/LuaTools.h index 9121660ec..0a1c4ccaa 100644 --- a/library/include/LuaTools.h +++ b/library/include/LuaTools.h @@ -380,7 +380,7 @@ namespace DFHack {namespace Lua { DFHACK_EXPORT extern lua_State *State; // Not exported; for use by the Core class - void Init(color_ostream &out); + bool Init(color_ostream &out); void Reset(color_ostream &out, const char *where); // Events signalled by the core diff --git a/plugins/dwarfmonitor.cpp b/plugins/dwarfmonitor.cpp index 216664a93..ca61ddb2e 100644 --- a/plugins/dwarfmonitor.cpp +++ b/plugins/dwarfmonitor.cpp @@ -1977,6 +1977,8 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector