Merge branch 'save-restore-behavior'
This commit is contained in:
@ -109,28 +109,29 @@ bool DatabaseExperiment::run()
|
||||
|
||||
simulator.clearListeners();
|
||||
|
||||
// Generate an experiment listener, that matches on any IP
|
||||
// event. It is used to forward to the injection
|
||||
// point. The +1 is needed, since even for the zeroth
|
||||
// dynamic instruction we need at least one breakpoint
|
||||
// event.
|
||||
BPSingleListener bp;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(injection_instr + 1);
|
||||
simulator.addListener(&bp);
|
||||
|
||||
if (!this->cb_before_fast_forward()) {
|
||||
continue;
|
||||
}
|
||||
fail::BaseListener * listener;
|
||||
while (true) {
|
||||
listener = simulator.resume();
|
||||
if (listener == &bp) {
|
||||
break;
|
||||
} else {
|
||||
bool should_continue = this->cb_during_fast_forward(listener);
|
||||
if (!should_continue)
|
||||
break; // Stop fast forwarding
|
||||
|
||||
// Do we need to fast-forward at all?
|
||||
if (injection_instr > 0) {
|
||||
// Create a listener that matches any IP event. It is used to
|
||||
// forward to the injection point.
|
||||
BPSingleListener bp;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(injection_instr);
|
||||
simulator.addListener(&bp);
|
||||
|
||||
fail::BaseListener * listener;
|
||||
while (true) {
|
||||
listener = simulator.resume();
|
||||
if (listener == &bp) {
|
||||
break;
|
||||
} else {
|
||||
bool should_continue = this->cb_during_fast_forward(listener);
|
||||
if (!should_continue)
|
||||
break; // Stop fast forwarding
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this->cb_after_fast_forward(listener)) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -19,13 +19,14 @@ aspect SaveState {
|
||||
advice execution (cpuLoop()) : order ("SaveState", "Breakpoints");
|
||||
|
||||
advice execution (cpuLoop()) : after () {
|
||||
if (!fail::save_bochs_request)
|
||||
return;
|
||||
assert(fail::sr_path.size() > 0 && "FATAL ERROR: tried to save state without valid path");
|
||||
SIM->save_state(fail::sr_path.c_str());
|
||||
std::cout << "[FAIL] Save finished" << std::endl;
|
||||
// TODO: Log-Level?
|
||||
fail::simulator.saveDone();
|
||||
// loop allows to call save() multiple times in a row
|
||||
while (fail::save_bochs_request) {
|
||||
assert(fail::sr_path.size() > 0 && "FATAL ERROR: tried to save state without valid path");
|
||||
SIM->save_state(fail::sr_path.c_str());
|
||||
std::cout << "[FAIL] Save finished" << std::endl;
|
||||
// TODO: Log-Level?
|
||||
fail::simulator.saveDone();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -321,18 +321,22 @@ bool CoredTester::run() {
|
||||
simulator.addListener(&l_fail_trace);
|
||||
|
||||
BPSingleListener bp;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
// TODO: why does this need a +1?
|
||||
bp.setCounter(injection_instr+1);
|
||||
simulator.addListener(&bp);
|
||||
|
||||
fail::BaseListener * listener = simulator.resume();
|
||||
fail::BaseListener *listener = 0;
|
||||
bool ok = true;
|
||||
|
||||
while ( ok && (listener == &l_fail_trace) ) {
|
||||
// m_log << "CP IP 0x" << std::hex << simulator.getCPU(0).getInstructionPointer() << std::endl;
|
||||
ok = cpoint.check(s_fail_trace, l_fail_trace.getTriggerInstructionPointer()) == Checkpoint::IDENTICAL;
|
||||
if(ok) listener = simulator.addListenerAndResume(&l_fail_trace);
|
||||
// do we have to fast-forward at all?
|
||||
if (injection_instr > 0) {
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(injection_instr);
|
||||
simulator.addListener(&bp);
|
||||
|
||||
listener = simulator.resume();
|
||||
|
||||
while ( ok && (listener == &l_fail_trace) ) {
|
||||
// m_log << "CP IP 0x" << std::hex << simulator.getCPU(0).getInstructionPointer() << std::endl;
|
||||
ok = cpoint.check(s_fail_trace, l_fail_trace.getTriggerInstructionPointer()) == Checkpoint::IDENTICAL;
|
||||
if(ok) listener = simulator.addListenerAndResume(&l_fail_trace);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned experiment_number = cpoint.getCount();
|
||||
@ -347,7 +351,7 @@ bool CoredTester::run() {
|
||||
|
||||
break;
|
||||
}
|
||||
if (listener != &bp) {
|
||||
if (listener != &bp && injection_instr > 0) {
|
||||
result = param.msg.add_result();
|
||||
handleEvent(*result, result->NOINJECTION, "WTF");
|
||||
|
||||
|
||||
@ -349,11 +349,11 @@ bool CoredVoter::run() {
|
||||
// Fast forward to injection address
|
||||
m_log << "Trying to inject @ instr #" << dec << injection_instr << endl;
|
||||
|
||||
if ((injection_instr + 2) > 0) {
|
||||
if (injection_instr > 0) {
|
||||
simulator.clearListeners();
|
||||
BPSingleListener bp;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(injection_instr + 2); // FIXME: FISHY!
|
||||
bp.setCounter(injection_instr);
|
||||
simulator.addListener(&bp);
|
||||
|
||||
fail::BaseListener * listener = simulator.resume();
|
||||
|
||||
@ -197,7 +197,7 @@ bool DCIAOKernelStructs::run() {
|
||||
simulator.addListener(&l_time_marker_print);
|
||||
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(injection_instr+1);
|
||||
bp.setCounter(injection_instr);
|
||||
simulator.addListener(&bp);
|
||||
|
||||
// Add vport listener
|
||||
|
||||
@ -253,7 +253,7 @@ bool FiascoFailExperiment::faultInjection()
|
||||
if(instr_offset > 0)
|
||||
{
|
||||
bp.setWatchInstructionPointer(ANY_ADDR); // Create new Breakpoint...
|
||||
bp.setCounter(instr_offset + 1); // ...to break when the IP for the fault injection is reached...
|
||||
bp.setCounter(instr_offset); // ...to break when the IP for the fault injection is reached...
|
||||
simulator.addListener(&bp); // ...and add it to the actual listeners
|
||||
|
||||
BaseListener *go = waitIOOrOther(true); // Resume simulation and log VGA-Output
|
||||
|
||||
@ -187,8 +187,7 @@ bool KESOgc::run()
|
||||
BPSingleListener bp;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
|
||||
// Fix offset by 1 error
|
||||
bp.setCounter(injection_instr + 1);
|
||||
bp.setCounter(injection_instr);
|
||||
|
||||
simulator.addListener(&bp);
|
||||
|
||||
|
||||
@ -161,7 +161,7 @@ bool KESOrefs::run()
|
||||
|
||||
BPSingleListener bp;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(injection_instr + 1);
|
||||
bp.setCounter(injection_instr);
|
||||
simulator.addListener(&bp);
|
||||
|
||||
bool inject = true;
|
||||
|
||||
@ -160,8 +160,7 @@ bool VEZSExperiment::run()
|
||||
BPSingleListener bp;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
|
||||
// Fix offset by 1 error
|
||||
bp.setCounter(injection_instr + 1);
|
||||
bp.setCounter(injection_instr);
|
||||
|
||||
simulator.addListener(&bp);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user