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)
develop
lethosor 2015-10-17 21:18:04 -04:00
parent 9ebaa4d695
commit c44ac8ec6e
5 changed files with 30 additions and 14 deletions

@ -1336,15 +1336,19 @@ Core::Core()
script_path_mutex = new mutex(); script_path_mutex = new mutex();
}; };
void Core::fatal (std::string output, bool deactivate) void Core::fatal (std::string output)
{ {
errorstate = true;
stringstream out; stringstream out;
out << output ; out << output ;
if(deactivate) if (output[output.size() - 1] != '\n')
out << '\n';
out << "DFHack will now deactivate.\n"; out << "DFHack will now deactivate.\n";
if(con.isInited()) if(con.isInited())
{ {
con.printerr("%s", out.str().c_str()); con.printerr("%s", out.str().c_str());
con.reset_color();
con.print("\n");
} }
fprintf(stderr, "%s\n", out.str().c_str()); fprintf(stderr, "%s\n", out.str().c_str());
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
@ -1395,7 +1399,7 @@ bool Core::Init()
delete vif; delete vif;
vif = NULL; vif = NULL;
errorstate = true; errorstate = true;
fatal(out.str(), true); fatal(out.str());
return false; return false;
} }
p = new DFHack::Process(vif); p = new DFHack::Process(vif);
@ -1403,7 +1407,7 @@ bool Core::Init()
if(!vinfo || !p->isIdentified()) if(!vinfo || !p->isIdentified())
{ {
fatal ("Not a known DF version.\n", true); fatal("Not a known DF version.\n");
errorstate = true; errorstate = true;
delete p; delete p;
p = NULL; p = NULL;
@ -1429,7 +1433,7 @@ bool Core::Init()
else if(con.init(false)) else if(con.init(false))
cerr << "Console is running.\n"; cerr << "Console is running.\n";
else else
fatal ("Console has failed to initialize!\n", false); cerr << "Console has failed to initialize!\n";
/* /*
// dump offsets to a file // dump offsets to a file
std::ofstream dump("offsets.log"); std::ofstream dump("offsets.log");
@ -1476,7 +1480,11 @@ bool Core::Init()
} }
// initialize common lua context // 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 // create mutex for syncing with interactive tasks
misc_data_mutex=new mutex(); misc_data_mutex=new mutex();

@ -1701,7 +1701,11 @@ lua_State *DFHack::Lua::Open(color_ostream &out, lua_State *state)
Lua::Core::InitCoreContext(); Lua::Core::InitCoreContext();
// load dfhack.lua // 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); lua_settop(state, 0);
if (!lua_checkstack(state, 64)) 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); 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) if (State) {
return; out.printerr("state already exists\n");
return false;
}
State = luaL_newstate(); State = luaL_newstate();
// Calls InitCoreContext after checking IsCoreContext // Calls InitCoreContext after checking IsCoreContext
Lua::Open(out, State); return (Lua::Open(out, State) != NULL);
} }
static void Lua::Core::InitCoreContext() static void Lua::Core::InitCoreContext()

@ -217,7 +217,7 @@ namespace DFHack
void operator=(Core const&); // Don't implement void operator=(Core const&); // Don't implement
// report error to user while failing // report error to user while failing
void fatal (std::string output, bool will_deactivate); void fatal (std::string output);
// 1 = fatal failure // 1 = fatal failure
bool errorstate; bool errorstate;

@ -380,7 +380,7 @@ namespace DFHack {namespace Lua {
DFHACK_EXPORT extern lua_State *State; DFHACK_EXPORT extern lua_State *State;
// Not exported; for use by the Core class // 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); void Reset(color_ostream &out, const char *where);
// Events signalled by the core // Events signalled by the core

@ -1977,6 +1977,8 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector <Plugin
)); ));
dm_lua::state = Lua::Open(out); dm_lua::state = Lua::Open(out);
if (dm_lua::state == NULL)
return CR_FAILURE;
return CR_OK; return CR_OK;
} }