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();
};
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();

@ -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()

@ -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;

@ -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

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