diff --git a/luprex/Makefile b/luprex/Makefile index 79c4083d..fe079efa 100644 --- a/luprex/Makefile +++ b/luprex/Makefile @@ -1,4 +1,4 @@ -all: main + OBJ_ERIS=\ obj/eris/lapi.o \ @@ -77,11 +77,6 @@ OBJ_DRV=\ obj/drv/sslutil.o\ --include $(OBJ_ERIS:%.o=%.d) --include $(OBJ_CORE:%.o=%.d) --include $(OBJ_DRV:%.o=%.d) - - ifeq ($(OS),linux) OPT=-g -O0 @@ -98,10 +93,15 @@ obj/core/%.o: cpp/core/%.cpp obj/drv/%.o: cpp/drv/%.cpp g++ $(OPT) -Wall -fvisibility=hidden -std=c++17 -I./ext/openssl -I./src/drv -c -MMD $< -o $@ +-include obj/drv/driver-linux.d + endif clean: rm -f main.exe main obj/*/*.* +-include $(OBJ_ERIS:%.o=%.d) +-include $(OBJ_CORE:%.o=%.d) +-include $(OBJ_DRV:%.o=%.d) diff --git a/luprex/cpp/core/drivenengine.cpp b/luprex/cpp/core/drivenengine.cpp index 717d49a5..623061b6 100644 --- a/luprex/cpp/core/drivenengine.cpp +++ b/luprex/cpp/core/drivenengine.cpp @@ -744,6 +744,9 @@ static void replay_sent_outgoing(EngineWrapper *w) { if ((nbytes > ndata) || (hash != SpookyHash::QkHash64(data, nbytes))) { return reset_wrapper(w, "nondeterministic in replay_sent_outgoing"); } + if (w->replay_cb_sent_outgoing != nullptr) { + w->replay_cb_sent_outgoing(w->replay_cb_vp, chid, ndata, data); + } w->engine->drv_sent_outgoing(chid, nbytes); } @@ -885,7 +888,6 @@ void replay_set_lua_source(EngineWrapper *w) { static void replaycore_initialize(EngineWrapper *w, const char *logfn) { - std::cerr << "Memhash before replaycore_initialize: " << eng::memhash() << std::endl; if (w->engine != nullptr) { return reset_wrapper(w, "Cannot initialize wrapper, it's already initialized."); return; @@ -904,7 +906,7 @@ static void replaycore_initialize(EngineWrapper *w, const char *logfn) { uint8_t code = rlog_uint8(w); int hash = rlog_uint32(w); if (!w->rlog->good()) { - return reset_wrapper(w, "logfile corrupt"); + return reset_wrapper(w, "logfile corrupt in initial step"); } if (hash != eng::memhash()) { return reset_wrapper(w, "nondeterminism detected in initial step"); @@ -926,9 +928,12 @@ static void replaycore_step(EngineWrapper *w) { } uint8_t code = rlog_uint8(w); + if (w->rlog->eof()) { + return reset_wrapper(w, "logfile terminated abruptly"); + } int hash = rlog_uint32(w); if (!w->rlog->good()) { - return reset_wrapper(w, "logfile corrupt"); + return reset_wrapper(w, "logfile corrupt in replay step"); } if (hash != eng::memhash()) { return reset_wrapper(w, "nondeterminism detected"); diff --git a/luprex/cpp/core/enginewrapper.hpp b/luprex/cpp/core/enginewrapper.hpp index e8323df8..b7d9d4a4 100644 --- a/luprex/cpp/core/enginewrapper.hpp +++ b/luprex/cpp/core/enginewrapper.hpp @@ -193,6 +193,32 @@ struct EngineWrapper { // void (*replay_step)(EngineWrapper *w); + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // CALLBACKS USED ONLY IN REPLAY MODE + // + // The driver can store function pointers here. If it does so, these + // functions will get called during replay_step operations. + // + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + void (*replay_cb_sent_outgoing)(void *vp, int chid, int nbytes, const char *data); + + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // VOID POINTER USED IN REPLAY CALLBACKS + // + // The driver can store a void pointer here. This void pointer will get passed + // to all the replay callbacks. + // + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + void *replay_cb_vp; + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // diff --git a/luprex/cpp/drv/driver-common.cpp b/luprex/cpp/drv/driver-common.cpp index 8166fd5c..669ff5cb 100644 --- a/luprex/cpp/drv/driver-common.cpp +++ b/luprex/cpp/drv/driver-common.cpp @@ -405,6 +405,12 @@ class Driver { return 0; } + static void replay_cb_sent_outgoing(void *vp, int chid, int ndata, const char *data) { + if (chid == 0) { + std::cerr.write(data, ndata); + } + } + int drive(int argc, char *argv[]) { // Remove the program name from argv. std::string program = argv[0]; @@ -413,6 +419,7 @@ class Driver { // Load the DLL and gain access to its functions. call_init_engine_wrapper(&engw); + engw.replay_cb_sent_outgoing = replay_cb_sent_outgoing; // If argv contains "replay ", do a replay, // and then skip everything else.