Merge branch 'save-restore-behavior'

This commit is contained in:
Horst Schirmeier
2015-04-08 17:45:40 +02:00
12 changed files with 74 additions and 48 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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