diff --git a/src/core/sal/bochs/BochsController.cc b/src/core/sal/bochs/BochsController.cc index f527c1e1..7b8aa140 100644 --- a/src/core/sal/bochs/BochsController.cc +++ b/src/core/sal/bochs/BochsController.cc @@ -9,6 +9,7 @@ namespace fail { #ifdef DANCEOS_RESTORE bx_bool restore_bochs_request = false; +bx_bool restore_bochs_finished = false; bx_bool save_bochs_request = false; std::string sr_path = ""; #endif @@ -106,6 +107,7 @@ void BochsController::restore(const std::string& path) { clearListeners(); restore_bochs_request = true; + restore_bochs_finished = false; BX_CPU(0)->async_event |= 1; sr_path = path; m_CurrFlow = m_Flows.getCurrent(); @@ -114,7 +116,6 @@ void BochsController::restore(const std::string& path) void BochsController::restoreDone() { - restore_bochs_request = false; m_Flows.toggle(m_CurrFlow); } diff --git a/src/core/sal/bochs/FailBochsGlobals.hpp b/src/core/sal/bochs/FailBochsGlobals.hpp index 8ee30bbf..50346dea 100644 --- a/src/core/sal/bochs/FailBochsGlobals.hpp +++ b/src/core/sal/bochs/FailBochsGlobals.hpp @@ -9,6 +9,7 @@ namespace fail { #ifdef DANCEOS_RESTORE extern bx_bool restore_bochs_request; +extern bx_bool restore_bochs_finished; extern bx_bool save_bochs_request; extern std::string sr_path; #endif diff --git a/src/core/sal/bochs/RestoreState.ah b/src/core/sal/bochs/RestoreState.ah index 9c9001f6..9ad278c2 100644 --- a/src/core/sal/bochs/RestoreState.ah +++ b/src/core/sal/bochs/RestoreState.ah @@ -13,10 +13,30 @@ #include "../SALInst.hpp" aspect RestoreState { - pointcut restoreState() = "void bx_sr_after_restore_state()"; + pointcut restoreState() = "void bx_sr_after_restore_state()"; + pointcut cpuLoop() = "void defineCPULoopJoinPoint(...)"; advice execution (restoreState()) : after () { + // did the experiment trigger this restore? + if (fail::restore_bochs_request) { + fail::restore_bochs_request = false; + fail::restore_bochs_finished = true; + } + } + + // Make sure the "RestoreState" aspect comes *after* the breakpoint stuff + // to create a simulator / experiment state very similar to when the state + // was saved. In an "after" advice this means it must get a *higher* + // precedence, therefore it's first in the order list. + advice execution (cpuLoop()) : order ("RestoreState", "Breakpoints"); + + advice execution (cpuLoop()) : after () + { + if (!fail::restore_bochs_finished) { + return; + } + fail::restore_bochs_finished = false; std::cout << "[FAIL] Restore finished" << std::endl; // TODO: Log-Level? fail::simulator.restoreDone();