Namespaces unified (sal+fi -> fail), Code cleanups (-> coding-style.txt), Doxygen-comments fixed.

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1319 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
adrian
2012-06-07 17:47:19 +00:00
parent cdd5379e19
commit b7d904140e
136 changed files with 1487 additions and 1554 deletions

View File

@ -10,12 +10,11 @@
#include "../../util/Logger.hpp"
using namespace std;
using namespace sal;
using namespace fi;
using namespace sal;
using namespace fail;
bool FaultCoverageExperiment::run()
{
// FIXME: This should be translated (-> English)!
/*
Experimentskizze:
- starte Gastsystem
@ -109,7 +108,7 @@ bool FaultCoverageExperiment::run()
#else
const size_t expected_size = sizeof(uint64_t)*8;
#endif
Register* pCAX = simulator.getRegisterManager().getSetOfType(RT_GP)->getRegister(sal::RID_CAX);
Register* pCAX = simulator.getRegisterManager().getSetOfType(RT_GP)->getRegister(RID_CAX);
assert(expected_size == pCAX->getWidth()); // we assume to get 32(64) bits...
regdata_t result = pCAX->getData();
res << "[FaultCoverageExperiment] Reg: " << pCAX->getName()

View File

@ -1,5 +1,5 @@
#ifndef __FAULTCOVERAGE_EXPERIMENT_HPP__
#define __FAULTCOVERAGE_EXPERIMENT_HPP__
#ifndef __FAULT_COVERAGE_EXPERIMENT_HPP__
#define __FAULT_COVERAGE_EXPERIMENT_HPP__
#include <iostream>
#include <fstream>
@ -17,13 +17,9 @@
breakpoints, traps, save/restore. Enable these in the configuration.
#endif
using namespace fi;
class FaultCoverageExperiment : public ExperimentFlow
{
public:
bool run();
class FaultCoverageExperiment : public fail::ExperimentFlow {
public:
bool run();
};
#endif // __FAULTCOVERAGE_EXPERIMENT_HPP__
#endif // __FAULT_COVERAGE_EXPERIMENT_HPP__

View File

@ -1,21 +1,21 @@
#include "MHTestCampaign.hpp"
#include <controller/CampaignManager.hpp>
#include <iostream>
using namespace fi;
#include "MHTestCampaign.hpp"
#include <controller/CampaignManager.hpp>
using namespace std;
using namespace fail;
bool MHTestCampaign::run()
{
MHExperimentData* datas[m_parameter_count];
cout << "[MHTestCampaign] Adding " << m_parameter_count << " values." << endl;
for(int i = 1; i <= m_parameter_count; i++){
datas[i] = new MHExperimentData;
datas[i]->msg.set_input(i);
campaignmanager.addParam(datas[i]);
usleep(100 * 1000); // 100 ms
for (int i = 1; i <= m_parameter_count; i++) {
datas[i] = new MHExperimentData;
datas[i]->msg.set_input(i);
campaignmanager.addParam(datas[i]);
usleep(100 * 1000); // 100 ms
}
campaignmanager.noMoreParameters();
// test results.
@ -23,8 +23,8 @@ bool MHTestCampaign::run()
int res = 0;
int res2 = 0;
MHExperimentData * exp;
for(int i = 1; i <= m_parameter_count; i++){
exp = static_cast<MHExperimentData*>( campaignmanager.getDone() );
for (int i = 1; i <= m_parameter_count; i++) {
exp = static_cast<MHExperimentData*>(campaignmanager.getDone());
f = exp->msg.output();
// cout << ">>>>>>>>>>>>>>> Output: " << i << "^2 = " << f << endl;
res += f;
@ -33,7 +33,7 @@ bool MHTestCampaign::run()
}
if (res == res2) {
cout << "TEST SUCCESSFUL FINISHED! " << "[" << res << "==" << res2 << "]" << endl;
}else{
} else {
cout << "TEST FAILED!" << " [" << res << "!=" << res2 << "]" << endl;
}
cout << "thats all... " << endl;

View File

@ -1,27 +1,23 @@
#ifndef __TESTCAMPAIGN_HPP__
#define __TESTCAMPAIGN_HPP__
#ifndef __MH_TEST_CAMPAIGN_HPP__
#define __MH_TEST_CAMPAIGN_HPP__
#include <controller/Campaign.hpp>
#include "controller/ExperimentData.hpp"
#include <experiments/MHTestCampaign/MHTest.pb.h>
using namespace fi;
class MHExperimentData : public ExperimentData {
public:
MHTestData msg;
public:
MHExperimentData() : ExperimentData(&msg){ };
class MHExperimentData : public fail::ExperimentData {
public:
MHTestData msg;
MHExperimentData() : fail::ExperimentData(&msg) { }
};
class MHTestCampaign : public Campaign {
int m_parameter_count;
public:
MHTestCampaign(int parametercount) : m_parameter_count(parametercount){};
virtual bool run();
class MHTestCampaign : public fail::Campaign {
private:
int m_parameter_count;
public:
MHTestCampaign(int parametercount) : m_parameter_count(parametercount) { }
bool run();
};
#endif
#endif // __MH_TEST_CAMPAIGN_HPP__

View File

@ -1,32 +1,35 @@
#include <iostream>
#include "experiment.hpp"
#include "MHTestCampaign.hpp"
#include "SAL/SALInst.hpp"
#include "SAL/Register.hpp"
#include "controller/Event.hpp"
#include <iostream>
// FIXME: You should provide a dependency check here!
using namespace std;
using namespace fail;
bool MHTestExperiment::run()
{
cout << "[MHTestExperiment] Let's go" << endl;
#if 0
fi::BPSingleEvent mainbp(0x00003c34);
sal::simulator.addEventAndWait(&mainbp);
BPSingleEvent mainbp(0x00003c34);
simulator.addEventAndWait(&mainbp);
cout << "[MHTestExperiment] breakpoint reached, saving" << endl;
sal::simulator.save("hello.main");
simulator.save("hello.main");
#else
MHExperimentData par;
if(m_jc.getParam(par)){
if (m_jc.getParam(par)) {
int num = par.msg.input();
cout << "[MHExperiment] stepping " << num << " instructions" << endl;
if (num > 0) {
fi::BPSingleEvent nextbp(fi::ANY_ADDR);
BPSingleEvent nextbp(ANY_ADDR);
nextbp.setCounter(num);
sal::simulator.addEventAndWait(&nextbp);
simulator.addEventAndWait(&nextbp);
}
sal::address_t instr = sal::simulator.getRegisterManager().getInstructionPointer();
address_t instr = simulator.getRegisterManager().getInstructionPointer();
cout << "[MHTestExperiment] Reached instruction: "
<< hex << instr
<< endl;
@ -36,8 +39,8 @@ bool MHTestExperiment::run()
cout << "No data for me? :(" << endl;
}
#endif
sal::simulator.clearEvents(this);
sal::simulator.terminate();
simulator.clearEvents(this);
simulator.terminate();
return true;
}

View File

@ -1,17 +1,17 @@
#ifndef __TESTEXPERIMENT_HPP__
#define __TESTEXPERIMENT_HPP__
#ifndef __MH_TEST_EXPERIMENT_HPP__
#define __MH_TEST_EXPERIMENT_HPP__
#include "controller/ExperimentFlow.hpp"
#include "jobserver/JobClient.hpp"
class MHTestExperiment : public fi::ExperimentFlow {
fi::JobClient m_jc;
public:
MHTestExperiment(){};
~MHTestExperiment(){};
bool run();
class MHTestExperiment : public fail::ExperimentFlow {
private:
fail::JobClient m_jc;
public:
MHTestExperiment() { }
~MHTestExperiment() { }
bool run();
};
#endif
#endif // __MH_TEST_EXPERIMENT_HPP__

View File

@ -1,25 +1,24 @@
#include "controller/CampaignManager.hpp"
#include "experiments/MHTestCampaign/MHTestCampaign.hpp"
#include <iostream>
#include <cstdlib>
#include "controller/CampaignManager.hpp"
#include "experiments/MHTestCampaign/MHTestCampaign.hpp"
using namespace std;
int main(int argc, char**argv){
int main(int argc, char**argv)
{
int paramcount = 0;
if (argc == 2)
paramcount = atoi(argv[1]);
else
paramcount = 10;
cout << "Running MHTestCampaign [" << paramcount << " parameter sets]" << endl;
int paramcount = 0;
if(argc == 2){
paramcount = atoi(argv[1]);
}else{
paramcount = 10;
}
cout << "Running MHTestCampaign [" << paramcount << " parameter sets]" << endl;
MHTestCampaign mhc(paramcount);
campaignmanager.runCampaign(&mhc);
cout << "Campaign complete." << endl;
return 0;
MHTestCampaign mhc(paramcount);
campaignmanager.runCampaign(&mhc);
cout << "Campaign complete." << endl;
return 0;
}

View File

@ -10,16 +10,14 @@
#include <google/protobuf/io/gzip_stream.h>
*/
using std::cout;
using std::endl;
using namespace fi;
using namespace sal;
using namespace std;
using namespace fail;
bool TracingTest::run()
{
cout << "[TracingTest] Setting up experiment" << endl;
#if 1
#if 0
// STEP 1: run until interesting function starts, and save state
BPSingleEvent breakpoint(0x00101658);
simulator.addEventAndWait(&breakpoint);
@ -33,17 +31,17 @@ bool TracingTest::run()
cout << "[TracingTest] enabling tracing" << endl;
TracingPlugin tp;
std::ofstream of("trace.pb");
ofstream of("trace.pb");
tp.setTraceFile(&of);
// this must be done *after* configuring the plugin:
simulator.addFlow(&tp);
cout << "[TracingTest] tracing 1000000 instructions" << endl;
BPSingleEvent timeout(fi::ANY_ADDR);
BPSingleEvent timeout(ANY_ADDR);
timeout.setCounter(1000000);
simulator.addEvent(&timeout);
InterruptEvent ie(fi::ANY_INTERRUPT);
InterruptEvent ie(ANY_INTERRUPT);
while (simulator.addEventAndWait(&ie) != &timeout) {
cout << "INTERRUPT #" << ie.getTriggerNumber() << "\n";
}
@ -54,7 +52,7 @@ bool TracingTest::run()
/*
// serialize trace to file
std::ofstream of("trace.pb");
ofstream of("trace.pb");
if (of.fail()) { return false; }
trace.SerializeToOstream(&of);
of.close();

View File

@ -3,10 +3,10 @@
#include "controller/ExperimentFlow.hpp"
class TracingTest : public fi::ExperimentFlow
class TracingTest : public fail::ExperimentFlow
{
public:
bool run();
};
#endif /* __TRACING_TEST_HPP__ */
#endif // __TRACING_TEST_HPP__

View File

@ -5,9 +5,8 @@
#include "../controller/Event.hpp"
#include "ExperimentDataExample/FaultCoverageExperiment.pb.h"
using std::cout;
using std::endl;
using std::hex;
using namespace std;
using namespace fail;
#define MEMTEST86_BREAKPOINT 0x4EDC
@ -16,22 +15,22 @@ bool DataRetrievalExperiment::run()
cout << "[getExperimentDataExperiment] Experiment start." << endl;
// Breakpoint address for Memtest86:
fi::BPSingleEvent mainbp(MEMTEST86_BREAKPOINT);
sal::simulator.addEventAndWait(&mainbp);
BPSingleEvent mainbp(MEMTEST86_BREAKPOINT);
simulator.addEventAndWait(&mainbp);
cout << "[getExperimentDataExperiment] Breakpoint reached." << endl;
FaultCoverageExperimentData* test = NULL;
cout << "[getExperimentDataExperiment] Getting ExperimentData (FaultCoverageExperiment)..." << endl;
test = sal::simulator.getExperimentData<FaultCoverageExperimentData>();
test = simulator.getExperimentData<FaultCoverageExperimentData>();
cout << "[getExperimentDataExperiment] Content of ExperimentData (FaultCoverageExperiment):" << endl;
if(test->has_data_name())
if (test->has_data_name())
cout << "Name: "<< test->data_name() << endl;
// m_instrptr1 augeben
cout << "m_instrptr1: " << hex << test->m_instrptr1() << endl;
// m_instrptr2 augeben
cout << "m_instrptr2: " << hex << test->m_instrptr2() << endl;
sal::simulator.clearEvents(this);
simulator.clearEvents(this);
return true; // experiment successful
}

View File

@ -3,7 +3,7 @@
#include "../controller/ExperimentFlow.hpp"
class DataRetrievalExperiment : public fi::ExperimentFlow
class DataRetrievalExperiment : public fail::ExperimentFlow
{
public:
DataRetrievalExperiment() { }
@ -11,4 +11,4 @@ class DataRetrievalExperiment : public fi::ExperimentFlow
bool run();
};
#endif /* __DATA_RETRIEVAL_EXPERIMENT_HPP__ */
#endif // __DATA_RETRIEVAL_EXPERIMENT_HPP__

View File

@ -1,5 +1,6 @@
#include <iostream>
#include <fstream>
#include "controller/ExperimentData.hpp"
#include "controller/ExperimentDataQueue.hpp"
#include "jobserver/JobServer.hpp"
@ -7,83 +8,56 @@
using namespace std;
int main(int argc, char* argv[]){
int main(int argc, char* argv[])
{
// FIXME: Translation missing.
ExperimentDataQueue exDaQu;
ExperimentData* readFromQueue;
fi::ExperimentDataQueue exDaQu;
fi::ExperimentData* readFromQueue;
//Daten in Struktur schreiben und in Datei speichern
// Daten in Struktur schreiben und in Datei speichern
ofstream fileWrite;
fileWrite.open("test.txt");
FaultCoverageExperimentData faultCovExWrite;
//Namen setzen
// Namen setzen
faultCovExWrite.set_data_name("Testfall 42");
//Instruktionpointer 1
// Instruktionpointer 1
faultCovExWrite.set_m_instrptr1(0x4711);
//Instruktionpointer 2
// Instruktionpointer 2
faultCovExWrite.set_m_instrptr2(0x1122);
//In ExperimentData verpacken
fi::ExperimentData exDaWrite(&faultCovExWrite);
//In Queue einbinden
// In ExperimentData verpacken
ExperimentData exDaWrite(&faultCovExWrite);
// In Queue einbinden
exDaQu.addData(&exDaWrite);
//Aus Queue holen
if(exDaQu.size() != 0)
// Aus Queue holen
if (exDaQu.size() != 0)
readFromQueue = exDaQu.getData();
//Serialisierung ueber Wrapper-Methode in ExperimentData
// Serialisierung ueber Wrapper-Methode in ExperimentData
readFromQueue->serialize(&fileWrite);
//cout << "Ausgabe: " << out << endl;
// cout << "Ausgabe: " << out << endl;
fileWrite.close();
//---------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//Daten aus Datei lesen und in Struktur schreiben
// Daten aus Datei lesen und in Struktur schreiben
ifstream fileRead;
fileRead.open("test.txt");
FaultCoverageExperimentData faultCovExRead;
fi::ExperimentData exDaRead(&faultCovExRead);
ExperimentData exDaRead(&faultCovExRead);
exDaRead.unserialize( &fileRead);
//Wenn Name, dann ausgeben
// Wenn Name, dann ausgeben
if(faultCovExRead.has_data_name()){
cout << "Name: "<< faultCovExRead.data_name() << endl;
}
//m_instrptr1 augeben
// m_instrptr1 augeben
cout << "m_instrptr1: " << faultCovExRead.m_instrptr1() << endl;
//m_instrptr2 augeben
// m_instrptr2 augeben
cout << "m_instrptr2: " << faultCovExRead.m_instrptr2() << endl;
fileRead.close();
return 0;
}

View File

@ -1,9 +1,6 @@
#ifndef __JUMP_AND_RUN_EXPERIMENT_HPP__
#define __JUMP_AND_RUN_EXPERIMENT_HPP__
// Author: Adrian Böckenkamp
// Date: 07.11.2011
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
@ -16,69 +13,64 @@
#error Breakpoint- and jump-events needed! Enable aspects first (see FailConfig.hpp)!
#endif
using namespace fi;
using namespace std;
using namespace sal;
using namespace fail;
class JumpAndRunExperiment : public fi::ExperimentFlow
{
public:
bool run()
{
/************************************
* Description of experiment flow. *
************************************/
// Wait for function entry adresss:
cout << "[JumpAndRunExperiment] Setting up experiment. Allowing to "
<< "start now." << endl;
BPEvent mainFuncEntry(0x3c1f);
simulator.addEvent(&mainFuncEntry);
if(&mainFuncEntry != simulator.waitAny())
{
cerr << "[JumpAndRunExperiment] Now, we are completely lost! "
<< "It's time to cry! :-(" << endl;
class JumpAndRunExperiment : public fail::ExperimentFlow {
public:
bool run()
{
/************************************
* Description of experiment flow. *
************************************/
// Wait for function entry adresss:
cout << "[JumpAndRunExperiment] Setting up experiment. Allowing to "
<< "start now." << endl;
BPEvent mainFuncEntry(0x3c1f);
simulator.addEvent(&mainFuncEntry);
if (&mainFuncEntry != simulator.waitAny()) {
cerr << "[JumpAndRunExperiment] Now, we are completely lost! "
<< "It's time to cry! :-(" << endl;
simulator.clearEvents(this);
return false;
}
else
cout << "[JumpAndRunExperiment] Entry of main function reached! "
<< " Let's see who's jumping around here..." << endl;
const unsigned COUNTER = 20000;
unsigned i = 0;
BxFlagsReg* pFlags = dynamic_cast<BxFlagsReg*>(simulator.
getRegisterManager().getSetOfType(RT_ST).snatch());
assert(pFlags != NULL && "FATAL ERROR: NULL ptr not expected!");
JumpEvent ev;
// Catch the next "counter" jumps:
while (++i <= COUNTER) {
ev.setWatchInstructionPointer(ANY_INSTR);
simulator.addEvent(&ev);
if (simulator.waitAny() != &ev) {
cerr << "[JumpAndRunExperiment] Damn! Something went "
<< "terribly wrong! Who added that event?! :-(" << endl;
simulator.clearEvents(this);
return false;
}
else
cout << "[JumpAndRunExperiment] Entry of main function reached! "
<< " Let's see who's jumping around here..." << endl;
const unsigned COUNTER = 20000;
unsigned i = 0;
BxFlagsReg* pFlags = dynamic_cast<BxFlagsReg*>(simulator.
getRegisterManager().getSetOfType(RT_ST).snatch());
assert(pFlags != NULL && "FATAL ERROR: NULL ptr not expected!");
JumpEvent ev;
// Catch the next "counter" jumps:
while(++i <= COUNTER)
{
ev.setWatchInstructionPointer(ANY_INSTR);
simulator.addEvent(&ev);
if(simulator.waitAny() != &ev)
{
cerr << "[JumpAndRunExperiment] Damn! Something went "
<< "terribly wrong! Who added that event?! :-(" << endl;
simulator.clearEvents(this);
return false;
}
else
cout << "[JumpAndRunExperiment] Jump detected. Instruction: "
<< "0x" hex << ev.getTriggerInstructionPointer()
<< " -- FLAGS [CF, ZF, OF, PF, SF] = ["
<< pFlags->getCarryFlag() << ", "
<< pFlags->getZeroFlag() << ", "
<< pFlags->getOverflowFlag() << ", "
<< pFlags->getParityFlag() << ", "
<< pFlags->getSignFlag() << "]." << endl;
}
cout << "[JumpAndRunExperiment] " << dec << counter
<< " jump(s) detected -- enough for today...exiting! :-)"
<< endl;
simulator.clearEvents(this);
return true;
cout << "[JumpAndRunExperiment] Jump detected. Instruction: "
<< "0x" hex << ev.getTriggerInstructionPointer()
<< " -- FLAGS [CF, ZF, OF, PF, SF] = ["
<< pFlags->getCarryFlag() << ", "
<< pFlags->getZeroFlag() << ", "
<< pFlags->getOverflowFlag() << ", "
<< pFlags->getParityFlag() << ", "
<< pFlags->getSignFlag() << "]." << endl;
}
cout << "[JumpAndRunExperiment] " << dec << counter
<< " jump(s) detected -- enough for today...exiting! :-)"
<< endl;
simulator.clearEvents(this);
return true;
}
};
#endif /* __JUMP_AND_RUN_EXPERIMENT_HPP__ */
#endif // __JUMP_AND_RUN_EXPERIMENT_HPP__

View File

@ -1,9 +1,6 @@
#ifndef __MEM_WRITE_EXPERIMENT_HPP__
#define __MEM_WRITE_EXPERIMENT_HPP__
// Author: Adrian Böckenkamp
// Date: 16.06.2011
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
@ -15,63 +12,60 @@
#error Event dependecies not satisfied! Enabled needed aspects in FailConfig.hpp!
#endif
using namespace fi;
using namespace std;
using sal::simulator;
using namespace fail;
class MemWriteExperiment : public ExperimentFlow
{
public:
bool run() // Example experiment (defines "what we wanna do")
{
/************************************
* Description of experiment flow. *
************************************/
class MemWriteExperiment : public fail::ExperimentFlow {
public:
bool run() // Example experiment (defines "what we wanna do")
{
/************************************
* Description of experiment flow. *
************************************/
// 1. Add some events (set up the experiment):
cout << "[MemWriteExperiment] Setting up experiment. Allowing to"
<< " start now." << endl;
MemWriteEvent mem1(0x000904F0), mem2(0x02ff0916), mem3(0x0050C8E8);
BPEvent breakpt(0x4ae6);
simulator.addEvent(&mem1);
simulator.addEvent(&mem2);
simulator.addEvent(&mem3);
simulator.addEvent(&breakpt);
// 1. Add some events (set up the experiment):
cout << "[MemWriteExperiment] Setting up experiment. Allowing to"
<< " start now." << endl;
MemWriteEvent mem1(0x000904F0), mem2(0x02ff0916), mem3(0x0050C8E8);
BPEvent breakpt(0x4ae6);
simulator.addEvent(&mem1);
simulator.addEvent(&mem2);
simulator.addEvent(&mem3);
simulator.addEvent(&breakpt);
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
cout << "[MemWriteExperiment] Waiting for condition (1) (\"(id1 &&"
<< " id2) || id3\") to become true..." << endl;
bool f1 = false, f2 = false, f3 = false, f4 = false;
while(!(f1 || f2 || f3 || f4))
{
BPEvent* pev = simulator.waitAny();
cout << "[MemWriteExperiment] Received event id=" << id
<< "." << endl;
if(pev == &mem4)
f4 = true;
if(pev == &mem3)
f3 = true;
if(pev == &mem2)
f2 = true;
if(pev == &mem1)
f1 = true;
}
cout << "[MemWriteExperiment] Condition (1) satisfied! Ready to "
<< "add next event..." << endl;
// 3. Add a new event now:
cout << "[MemWriteExperiment] Adding new Event..."; cout.flush();
simulator.clearEvents(); // remove residual events in the buffer
// (we're just interested in the new event)
simulator.save("./bochs_save_point");
cout << "done!" << endl;
// 4. Continue simulation (waitAny) and inject bitflip:
// ...
simulator.clearEvents(this);
return true;
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
cout << "[MemWriteExperiment] Waiting for condition (1) (\"(id1 &&"
<< " id2) || id3\") to become true..." << endl;
bool f1 = false, f2 = false, f3 = false, f4 = false;
while (!(f1 || f2 || f3 || f4)) {
BPEvent* pev = simulator.waitAny();
cout << "[MemWriteExperiment] Received event id=" << id
<< "." << endl;
if(pev == &mem4)
f4 = true;
if(pev == &mem3)
f3 = true;
if(pev == &mem2)
f2 = true;
if(pev == &mem1)
f1 = true;
}
cout << "[MemWriteExperiment] Condition (1) satisfied! Ready to "
<< "add next event..." << endl;
// 3. Add a new event now:
cout << "[MemWriteExperiment] Adding new Event..."; cout.flush();
simulator.clearEvents(); // remove residual events in the buffer
// (we're just interested in the new event)
simulator.save("./bochs_save_point");
cout << "done!" << endl;
// 4. Continue simulation (waitAny) and inject bitflip:
// ...
simulator.clearEvents(this);
return true;
}
};
#endif /* __MEM_WRITE_EXPERIMENT_HPP__ */
#endif // __MEM_WRITE_EXPERIMENT_HPP__

View File

@ -1,66 +1,60 @@
#ifndef __MY_EXPERIMENT_HPP__
#define __MY_EXPERIMENT_HPP__
// Author: Adrian Böckenkamp
// Date: 16.06.2011
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
#include "../SAL/SALInst.hpp"
using namespace fi;
using namespace std;
using sal::simulator;
using namespace fail;
class MyExperiment : public fi::ExperimentFlow
{
public:
bool run() // Example experiment (defines "what we wanna do")
{
/************************************
* Description of experiment flow. *
************************************/
// 1. Add some events (set up the experiment):
cout << "[MyExperiment] Setting up experiment. Allowing to start"
<< " now." << endl;
BPEvent ev1(0x8048A00), ev2(0x8048F01), ev3(0x3c1f);
simulator.addEvent(&ev1);
simulator.addEvent(&ev2);
simulator.addEvent(&ev3);
class MyExperiment : public fail::ExperimentFlow {
public:
bool run() // Example experiment (defines "what we wanna do")
{
/************************************
* Description of experiment flow. *
************************************/
// 1. Add some events (set up the experiment):
cout << "[MyExperiment] Setting up experiment. Allowing to start"
<< " now." << endl;
BPEvent ev1(0x8048A00), ev2(0x8048F01), ev3(0x3c1f);
simulator.addEvent(&ev1);
simulator.addEvent(&ev2);
simulator.addEvent(&ev3);
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
BPEvent* pev;
cout << "[MyExperiment] Waiting for condition (1) (\"(id1 && id2)"
<< " || id3\") to become true..." << endl;
bool f1 = false, f2 = false, f3 = false;
while(!((f1 && f2) || f3))
{
pev = simulator.waitAny();
cout << "[MyExperiment] Received event id=" << pev->getId()
<< "." << endl;
if(pev == &ev3)
f3 = true;
if(pev == &ev2)
f2 = true;
if(pev == &ev1)
f1 = true;
}
cout << "[MyExperiment] Condition (1) satisfied! Ready..." << endl;
// Remove residual (for all active experiments!)
// events in the buffer:
simulator.clearEvents();
BPEvent foobar(ANY_ADDR);
foobar.setCounter(400);
cout << "[MyExperiment] Adding breakpoint-event, firing after the"
<< " next 400 instructions..."; cout.flush();
simulator.addEventAndWait(&foobar);
cout << "cought! Exiting now." << endl;
simulator.clearEvents(this);
return true;
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
BPEvent* pev;
cout << "[MyExperiment] Waiting for condition (1) (\"(id1 && id2)"
<< " || id3\") to become true..." << endl;
bool f1 = false, f2 = false, f3 = false;
while (!((f1 && f2) || f3)) {
pev = simulator.waitAny();
cout << "[MyExperiment] Received event id=" << pev->getId()
<< "." << endl;
if(pev == &ev3)
f3 = true;
if(pev == &ev2)
f2 = true;
if(pev == &ev1)
f1 = true;
}
cout << "[MyExperiment] Condition (1) satisfied! Ready..." << endl;
// Remove residual (for all active experiments!)
// events in the buffer:
simulator.clearEvents();
BPEvent foobar(ANY_ADDR);
foobar.setCounter(400);
cout << "[MyExperiment] Adding breakpoint-event, firing after the"
<< " next 400 instructions..."; cout.flush();
simulator.addEventAndWait(&foobar);
cout << "cought! Exiting now." << endl;
simulator.clearEvents(this);
return true;
}
};
#endif /* __MY_EXPERIMENT_HPP__ */
#endif // __MY_EXPERIMENT_HPP__

View File

@ -1,9 +1,6 @@
#ifndef __SINGLE_STEPPING_EXPERIMENT_HPP__
#define __SINGLE_STEPPING_EXPERIMENT_HPP__
// Author: Adrian Böckenkamp
// Date: 09.11.2011
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
@ -16,52 +13,48 @@
#error Breakpoint-events needed! Enable aspect first (see FailConfig.hpp)!
#endif
using namespace fi;
using namespace std;
using namespace sal;
using namespace fail;
#define FUNCTION_ENTRY_ADDRESS 0x3c1f
class SingleSteppingExperiment : public fi::ExperimentFlow
{
public:
bool run()
{
/************************************
* Description of experiment flow. *
************************************/
// Wait for function entry adresss:
cout << "[SingleSteppingExperiment] Setting up experiment. Allowing"
<< " to start now." << endl;
BPEvent mainFuncEntry(FUNCTION_ENTRY_ADDRESS);
simulator.addEvent(&mainFuncEntry);
if(&mainFuncEntry != simulator.waitAny())
{
cerr << "[SingleSteppingExperiment] Now, we are completely lost!"
<< " It's time to cry! :-(" << endl;
simulator.clearEvents(this);
return false;
}
cout << "[SingleSteppingExperiment] Entry of main function reached!"
<< " Beginning single-stepping..." << endl;
char action;
while(true)
{
BPEvent bp(ANY_ADDR);
simulator.addEvent(&bp);
simulator.waitAny();
cout << "0x" << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
cout << "Continue (y/n)? ";
cin >> action; cin.sync(); cin.clear();
if(action != 'y')
break;
}
class SingleSteppingExperiment : public fail::ExperimentFlow {
public:
bool run()
{
/************************************
* Description of experiment flow. *
************************************/
// Wait for function entry adresss:
cout << "[SingleSteppingExperiment] Setting up experiment. Allowing"
<< " to start now." << endl;
BPEvent mainFuncEntry(FUNCTION_ENTRY_ADDRESS);
simulator.addEvent(&mainFuncEntry);
if (&mainFuncEntry != simulator.waitAny()) {
cerr << "[SingleSteppingExperiment] Now, we are completely lost!"
<< " It's time to cry! :-(" << endl;
simulator.clearEvents(this);
return true;
return false;
}
cout << "[SingleSteppingExperiment] Entry of main function reached!"
<< " Beginning single-stepping..." << endl;
char action;
while (true) {
BPEvent bp(ANY_ADDR);
simulator.addEvent(&bp);
simulator.waitAny();
cout << "0x" << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
cout << "Continue (y/n)? ";
cin >> action; cin.sync(); cin.clear();
if (action != 'y')
break;
}
simulator.clearEvents(this);
return true;
}
};
#endif /* __SINGLE_STEPPING_EXPERIMENT_HPP__ */
#endif // __SINGLE_STEPPING_EXPERIMENT_HPP__

View File

@ -8,8 +8,8 @@
aspect hscsimple {
hscsimpleExperiment experiment;
advice execution ("void sal::SimulatorController::initExperiments()") : after () {
sal::simulator.addFlow(&experiment);
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
fail::simulator.addFlow(&experiment);
}
};

View File

@ -14,8 +14,8 @@
#include "plugins/tracing/TracingPlugin.hpp"
char const * const trace_filename = "trace.pb";
using namespace fi;
using std::endl;
using namespace std;
using namespace fail;
char const * const results_csv = "chksumoostubs.csv";
@ -24,9 +24,9 @@ char const * const results_csv = "chksumoostubs.csv";
// [i1, i2]: interval of instruction numbers, counted from experiment
// begin
struct equivalence_class {
sal::address_t data_address;
address_t data_address;
int instr1, instr2;
sal::address_t instr2_absolute; // FIXME we could record them all here
address_t instr2_absolute; // FIXME we could record them all here
};
bool ChecksumOOStuBSCampaign::run()
@ -62,26 +62,26 @@ bool ChecksumOOStuBSCampaign::run()
// set of equivalence classes that need one (rather: eight, one for
// each bit in that byte) experiment to determine them all
std::vector<equivalence_class> ecs_need_experiment;
vector<equivalence_class> ecs_need_experiment;
// set of equivalence classes that need no experiment, because we know
// they'd be identical to the golden run
std::vector<equivalence_class> ecs_no_effect;
vector<equivalence_class> ecs_no_effect;
equivalence_class current_ec;
// map for efficient access when results come in
std::map<ChecksumOOStuBSExperimentData *, unsigned> experiment_ecs;
map<ChecksumOOStuBSExperimentData *, unsigned> experiment_ecs;
// experiment count
int count = 0;
// XXX do it the other way around: iterate over trace, search addresses
// for every injection address ...
for (MemoryMap::iterator it = mm.begin(); it != mm.end(); ++it) {
std::cerr << ".";
sal::address_t data_address = *it;
cerr << ".";
address_t data_address = *it;
current_ec.instr1 = 0;
int instr = 0;
sal::address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
Trace_Event ev;
ps.reset();
@ -136,7 +136,7 @@ bool ChecksumOOStuBSCampaign::run()
// store index into ecs_need_experiment
experiment_ecs[d] = ecs_need_experiment.size() - 1;
fi::campaignmanager.addParam(d);
campaignmanager.addParam(d);
++count;
}
} else if (ev.accesstype() == ev.WRITE) {
@ -173,7 +173,7 @@ bool ChecksumOOStuBSCampaign::run()
ecs_no_effect.push_back(current_ec);
}
fi::campaignmanager.noMoreParameters();
campaignmanager.noMoreParameters();
log << "done enqueueing parameter sets (" << count << ")." << endl;
log << "equivalence classes generated:"
@ -182,11 +182,11 @@ bool ChecksumOOStuBSCampaign::run()
// statistics
unsigned long num_dumb_experiments = 0;
for (std::vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
for (vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
it != ecs_need_experiment.end(); ++it) {
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
}
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
it != ecs_no_effect.end(); ++it) {
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
}
@ -197,7 +197,7 @@ bool ChecksumOOStuBSCampaign::run()
results << "ec_instr1\tec_instr2\tec_instr2_absolute\tec_data_address\tbitnr\tresulttype\tresult0\tresult1\tresult2\tfinish_reached\tlatest_ip\terror_corrected\tdetails" << endl;
// store no-effect "experiment" results
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
it != ecs_no_effect.end(); ++it) {
results
<< (*it).instr1 << "\t"
@ -215,10 +215,10 @@ bool ChecksumOOStuBSCampaign::run()
// collect results
ChecksumOOStuBSExperimentData *res;
int rescount = 0;
while ((res = static_cast<ChecksumOOStuBSExperimentData *>(fi::campaignmanager.getDone()))) {
while ((res = static_cast<ChecksumOOStuBSExperimentData *>(campaignmanager.getDone()))) {
rescount++;
std::map<ChecksumOOStuBSExperimentData *, unsigned>::iterator it =
map<ChecksumOOStuBSExperimentData *, unsigned>::iterator it =
experiment_ecs.find(res);
if (it == experiment_ecs.end()) {
results << "WTF, didn't find res!" << endl;

View File

@ -1,19 +1,19 @@
#ifndef __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
#define __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
#define __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
#include "controller/Campaign.hpp"
#include "controller/ExperimentData.hpp"
#include "checksum-oostubs.pb.h"
class ChecksumOOStuBSExperimentData : public fi::ExperimentData {
class ChecksumOOStuBSExperimentData : public fail::ExperimentData {
public:
OOStuBSProtoMsg msg;
ChecksumOOStuBSExperimentData() : fi::ExperimentData(&msg) {}
ChecksumOOStuBSExperimentData() : fail::ExperimentData(&msg) {}
};
class ChecksumOOStuBSCampaign : public fi::Campaign {
class ChecksumOOStuBSCampaign : public fail::Campaign {
public:
virtual bool run();
};
#endif
#endif // __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__

View File

@ -5,11 +5,9 @@
#include <unistd.h>
#include "util/Logger.hpp"
#include "experiment.hpp"
#include "experimentInfo.hpp"
#include "campaign.hpp"
#include "SAL/SALConfig.hpp"
#include "SAL/SALInst.hpp"
#include "SAL/Memory.hpp"
@ -21,7 +19,8 @@
#include "ecc_region.hpp"
using std::endl;
using namespace std;
using namespace fail;
// Check if configuration dependencies are satisfied:
#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \
@ -33,33 +32,33 @@ bool ChecksumOOStuBSExperiment::run()
{
char const *statename = "checksum-oostubs.state";
Logger log("Checksum-OOStuBS", false);
fi::BPSingleEvent bp;
BPSingleEvent bp;
log << "startup" << endl;
#if 1
// STEP 0: record memory map with addresses of "interesting" objects
fi::GuestEvent g;
GuestEvent g;
while (true) {
sal::simulator.addEventAndWait(&g);
std::cout << g.getData() << std::flush;
simulator.addEventAndWait(&g);
cout << g.getData() << flush;
}
#elif 0
// STEP 1: run until interesting function starts, and save state
bp.setWatchInstructionPointer(OOSTUBS_FUNC_ENTRY);
sal::simulator.addEventAndWait(&bp);
simulator.addEventAndWait(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer() << endl;
log << "error_corrected = " << std::dec << ((int)sal::simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
sal::simulator.save(statename);
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
simulator.save(statename);
assert(bp.getTriggerInstructionPointer() == OOSTUBS_FUNC_ENTRY);
assert(sal::simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
assert(simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
#elif 1
// STEP 2: record trace for fault-space pruning
log << "restoring state" << endl;
sal::simulator.restore(statename);
log << "EIP = " << std::hex << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
assert(sal::simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
simulator.restore(statename);
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
assert(simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
log << "enabling tracing" << endl;
TracingPlugin tp;
@ -73,37 +72,37 @@ bool ChecksumOOStuBSExperiment::run()
// record trace
char const *tracefile = "trace.pb";
std::ofstream of(tracefile);
ofstream of(tracefile);
tp.setTraceFile(&of);
// this must be done *after* configuring the plugin:
sal::simulator.addFlow(&tp);
simulator.addFlow(&tp);
bp.setWatchInstructionPointer(fi::ANY_ADDR);
bp.setWatchInstructionPointer(ANY_ADDR);
bp.setCounter(OOSTUBS_NUMINSTR);
sal::simulator.addEvent(&bp);
fi::BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
sal::simulator.addEvent(&func_finish);
simulator.addEvent(&bp);
BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
simulator.addEvent(&func_finish);
if (sal::simulator.waitAny() == &func_finish) {
if (simulator.waitAny() == &func_finish) {
log << "experiment reached finish()" << endl;
// FIXME add instruction counter to SimulatorController
sal::simulator.waitAny();
simulator.waitAny();
}
log << "experiment finished after " << std::dec << OOSTUBS_NUMINSTR << " instructions" << endl;
log << "experiment finished after " << dec << OOSTUBS_NUMINSTR << " instructions" << endl;
uint32_t results[OOSTUBS_RESULTS_BYTES / sizeof(uint32_t)];
sal::simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
for (unsigned i = 0; i < sizeof(results) / sizeof(*results); ++i) {
log << "results[" << i << "]: " << std::dec << results[i] << endl;
log << "results[" << i << "]: " << dec << results[i] << endl;
}
sal::simulator.removeFlow(&tp);
simulator.removeFlow(&tp);
// serialize trace to file
if (of.fail()) {
log << "failed to write " << tracefile << endl;
sal::simulator.clearEvents(this);
simulator.clearEvents(this);
return false;
}
of.close();
@ -117,7 +116,7 @@ bool ChecksumOOStuBSExperiment::run()
// STEP 3: The actual experiment.
log << "restoring state" << endl;
sal::simulator.restore(statename);
simulator.restore(statename);
// get an experiment parameter set
log << "asking job server for experiment parameters" << endl;
@ -125,7 +124,7 @@ bool ChecksumOOStuBSExperiment::run()
if (!m_jc.getParam(param)) {
log << "Dying." << endl;
// communicate that we were told to die
sal::simulator.terminate(1);
simulator.terminate(1);
}
/*
// XXX debug
@ -142,49 +141,49 @@ bool ChecksumOOStuBSExperiment::run()
log << "job " << id << " instr " << instr_offset << " mem " << mem_addr << "+" << bit_offset << endl;
// XXX debug
std::stringstream fname;
stringstream fname;
fname << "job." << ::getpid();
std::ofstream job(fname.str().c_str());
ofstream job(fname.str().c_str());
job << "job " << id << " instr " << instr_offset << " (" << param.msg.instr_address() << ") mem " << mem_addr << "+" << bit_offset << endl;
job.close();
// reaching finish() could happen before OR after FI
fi::BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
sal::simulator.addEvent(&func_finish);
BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
simulator.addEvent(&func_finish);
bool finish_reached = false;
// no need to wait if offset is 0
if (instr_offset > 0) {
// XXX test this with coolchecksum first (or reassure with sanity checks)
// XXX could be improved with intermediate states (reducing runtime until injection)
bp.setWatchInstructionPointer(fi::ANY_ADDR);
bp.setWatchInstructionPointer(ANY_ADDR);
bp.setCounter(instr_offset);
sal::simulator.addEvent(&bp);
simulator.addEvent(&bp);
// finish() before FI?
if (sal::simulator.waitAny() == &func_finish) {
if (simulator.waitAny() == &func_finish) {
finish_reached = true;
log << "experiment reached finish() before FI" << endl;
// wait for bp
sal::simulator.waitAny();
simulator.waitAny();
}
}
// --- fault injection ---
sal::MemoryManager& mm = sal::simulator.getMemoryManager();
sal::byte_t data = mm.getByte(mem_addr);
sal::byte_t newdata = data ^ (1 << bit_offset);
MemoryManager& mm = simulator.getMemoryManager();
byte_t data = mm.getByte(mem_addr);
byte_t newdata = data ^ (1 << bit_offset);
mm.setByte(mem_addr, newdata);
// note at what IP we did it
int32_t injection_ip = sal::simulator.getRegisterManager().getInstructionPointer();
int32_t injection_ip = simulator.getRegisterManager().getInstructionPointer();
param.msg.set_injection_ip(injection_ip);
log << "fault injected @ ip " << injection_ip
<< " 0x" << std::hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
<< " 0x" << hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
// sanity check
if (param.msg.has_instr_address() &&
injection_ip != param.msg.instr_address()) {
std::stringstream ss;
stringstream ss;
ss << "SANITY CHECK FAILED: " << injection_ip
<< " != " << param.msg.instr_address();
log << ss.str() << endl;
@ -192,7 +191,7 @@ bool ChecksumOOStuBSExperiment::run()
param.msg.set_latest_ip(injection_ip);
param.msg.set_details(ss.str());
sal::simulator.clearEvents();
simulator.clearEvents();
m_jc.sendResult(param);
continue;
}
@ -209,27 +208,27 @@ bool ChecksumOOStuBSExperiment::run()
// * a correct result[0-2]
// catch traps as "extraordinary" ending
fi::TrapEvent ev_trap(fi::ANY_TRAP);
sal::simulator.addEvent(&ev_trap);
TrapEvent ev_trap(ANY_TRAP);
simulator.addEvent(&ev_trap);
// OOStuBS' way to terminally halt (CLI+HLT)
fi::BPSingleEvent ev_halt(OOSTUBS_FUNC_CPU_HALT);
sal::simulator.addEvent(&ev_halt);
BPSingleEvent ev_halt(OOSTUBS_FUNC_CPU_HALT);
simulator.addEvent(&ev_halt);
// remaining instructions until "normal" ending
fi::BPSingleEvent ev_done(fi::ANY_ADDR);
BPSingleEvent ev_done(ANY_ADDR);
ev_done.setCounter(OOSTUBS_NUMINSTR + OOSTUBS_RECOVERYINSTR - instr_offset);
sal::simulator.addEvent(&ev_done);
simulator.addEvent(&ev_done);
/*
// XXX debug
log << "enabling tracing" << endl;
TracingPlugin tp;
tp.setLogIPOnly(true);
tp.setOstream(&std::cout);
tp.setOstream(&cout);
// this must be done *after* configuring the plugin:
sal::simulator.addFlow(&tp);
simulator.addFlow(&tp);
*/
fi::BaseEvent* ev = sal::simulator.waitAny();
BaseEvent* ev = simulator.waitAny();
// Do we reach finish() while waiting for ev_trap/ev_done?
if (ev == &func_finish) {
@ -237,40 +236,40 @@ bool ChecksumOOStuBSExperiment::run()
log << "experiment reached finish()" << endl;
// wait for ev_trap/ev_done
ev = sal::simulator.waitAny();
ev = simulator.waitAny();
}
// record resultdata, finish_reached and error_corrected regardless of result
uint32_t results[OOSTUBS_RESULTS_BYTES / sizeof(uint32_t)];
sal::simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
for (unsigned i = 0; i < sizeof(results) / sizeof(*results); ++i) {
log << "results[" << i << "]: " << std::dec << results[i] << endl;
log << "results[" << i << "]: " << dec << results[i] << endl;
param.msg.add_resultdata(results[i]);
}
param.msg.set_finish_reached(finish_reached);
int32_t error_corrected = sal::simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED);
int32_t error_corrected = simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED);
param.msg.set_error_corrected(error_corrected);
param.msg.set_latest_ip(sal::simulator.getRegisterManager().getInstructionPointer());
param.msg.set_latest_ip(simulator.getRegisterManager().getInstructionPointer());
if (ev == &ev_done) {
log << std::dec << "Result FINISHED" << endl;
log << dec << "Result FINISHED" << endl;
param.msg.set_resulttype(param.msg.FINISHED);
} else if (ev == &ev_halt) {
log << std::dec << "Result HALT" << endl;
log << dec << "Result HALT" << endl;
param.msg.set_resulttype(param.msg.HALT);
} else if (ev == &ev_trap) {
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
param.msg.set_resulttype(param.msg.TRAP);
std::stringstream ss;
stringstream ss;
ss << ev_trap.getTriggerNumber();
param.msg.set_details(ss.str());
} else {
log << std::dec << "Result WTF?" << endl;
log << dec << "Result WTF?" << endl;
param.msg.set_resulttype(param.msg.UNKNOWN);
std::stringstream ss;
ss << "eventid " << ev->getId() << " EIP " << sal::simulator.getRegisterManager().getInstructionPointer();
stringstream ss;
ss << "eventid " << ev->getId() << " EIP " << simulator.getRegisterManager().getInstructionPointer();
param.msg.set_details(ss.str());
}
m_jc.sendResult(param);
@ -278,5 +277,5 @@ bool ChecksumOOStuBSExperiment::run()
}
#endif
// Explicitly terminate, or the simulator will continue to run.
sal::simulator.terminate();
simulator.terminate();
}

View File

@ -1,14 +1,14 @@
#ifndef __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
#define __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
#define __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
#include "controller/ExperimentFlow.hpp"
#include "jobserver/JobClient.hpp"
class ChecksumOOStuBSExperiment : public fi::ExperimentFlow {
fi::JobClient m_jc;
class ChecksumOOStuBSExperiment : public fail::ExperimentFlow {
fail::JobClient m_jc;
public:
ChecksumOOStuBSExperiment() : m_jc("ios.cs.tu-dortmund.de") {}
bool run();
};
#endif
#endif // __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__

View File

@ -1,5 +1,5 @@
#ifndef __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
// FIXME autogenerate this
@ -48,4 +48,4 @@
#endif
#endif
#endif // __EXPERIMENT_INFO_HPP__

View File

@ -7,7 +7,7 @@
int main(int argc, char **argv)
{
ChecksumOOStuBSCampaign c;
if (fi::campaignmanager.runCampaign(&c)) {
if (fail::campaignmanager.runCampaign(&c)) {
return 0;
} else {
return 1;

View File

@ -12,8 +12,8 @@
char const * const trace_filename = "trace.pb";
#endif
using namespace fi;
using std::endl;
using namespace std;
using namespace fail;
char const * const results_csv = "coolcampaign.csv";
@ -24,7 +24,7 @@ char const * const results_csv = "coolcampaign.csv";
struct equivalence_class {
unsigned byte_offset;
int instr1, instr2;
sal::address_t instr2_absolute; // FIXME we could record them all here
address_t instr2_absolute; // FIXME we could record them all here
};
bool CoolChecksumCampaign::run()
@ -52,18 +52,18 @@ bool CoolChecksumCampaign::run()
d->msg.set_instr_offset(instr_offset);
d->msg.set_bit_offset(bit_offset);
fi::campaignmanager.addParam(d);
campaignmanager.addParam(d);
++count;
}
}
fi::campaignmanager.noMoreParameters();
campaignmanager.noMoreParameters();
log << "done enqueueing parameter sets (" << count << ")." << endl;
// collect results
CoolChecksumExperimentData *res;
int rescount = 0;
results << "injection_ip\tinstr_offset\tinjection_bit\tresulttype\tresultdata\terror_corrected\tdetails" << endl;
while ((res = static_cast<CoolChecksumExperimentData *>(fi::campaignmanager.getDone()))) {
while ((res = static_cast<CoolChecksumExperimentData *>(campaignmanager.getDone()))) {
rescount++;
results
@ -87,10 +87,10 @@ bool CoolChecksumCampaign::run()
// set of equivalence classes that need one (rather: eight, one for
// each bit in that byte) experiment to determine them all
std::vector<equivalence_class> ecs_need_experiment;
vector<equivalence_class> ecs_need_experiment;
// set of equivalence classes that need no experiment, because we know
// they'd be identical to the golden run
std::vector<equivalence_class> ecs_no_effect;
vector<equivalence_class> ecs_no_effect;
equivalence_class current_ec;
@ -103,7 +103,7 @@ bool CoolChecksumCampaign::run()
// accesses to that address ...
// XXX reorganizing the trace for efficient seeks could speed this up
int instr = 0;
sal::address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
Trace_Event ev;
ps.reset();
@ -180,11 +180,11 @@ bool CoolChecksumCampaign::run()
// statistics
int num_dumb_experiments = 0;
for (std::vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
for (vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
it != ecs_need_experiment.end(); ++it) {
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
}
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
it != ecs_no_effect.end(); ++it) {
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
}
@ -192,9 +192,9 @@ bool CoolChecksumCampaign::run()
" experiments to " << ecs_need_experiment.size() * 8 << endl;
// map for efficient access when results come in
std::map<CoolChecksumExperimentData *, equivalence_class *> experiment_ecs;
map<CoolChecksumExperimentData *, equivalence_class *> experiment_ecs;
int count = 0;
for (std::vector<equivalence_class>::iterator it = ecs_need_experiment.begin();
for (vector<equivalence_class>::iterator it = ecs_need_experiment.begin();
it != ecs_need_experiment.end(); ++it) {
for (int bitnr = 0; bitnr < 8; ++bitnr) {
CoolChecksumExperimentData *d = new CoolChecksumExperimentData;
@ -205,11 +205,11 @@ bool CoolChecksumCampaign::run()
experiment_ecs[d] = &(*it);
fi::campaignmanager.addParam(d);
campaignmanager.addParam(d);
++count;
}
}
fi::campaignmanager.noMoreParameters();
campaignmanager.noMoreParameters();
log << "done enqueueing parameter sets (" << count << ")." << endl;
// CSV header
@ -217,7 +217,7 @@ bool CoolChecksumCampaign::run()
// store no-effect "experiment" results
// (for comparison reasons; we'll store that more compactly later)
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
it != ecs_no_effect.end(); ++it) {
for (int bitnr = 0; bitnr < 8; ++bitnr) {
for (int instr = (*it).instr1; instr <= (*it).instr2; ++instr) {
@ -236,7 +236,7 @@ bool CoolChecksumCampaign::run()
// collect results
CoolChecksumExperimentData *res;
int rescount = 0;
while ((res = static_cast<CoolChecksumExperimentData *>(fi::campaignmanager.getDone()))) {
while ((res = static_cast<CoolChecksumExperimentData *>(campaignmanager.getDone()))) {
rescount++;
equivalence_class *ec = experiment_ecs[res];

View File

@ -1,20 +1,19 @@
#ifndef __COOLCAMPAIGN_HPP__
#define __COOLCAMPAIGN_HPP__
#define __COOLCAMPAIGN_HPP__
#include "controller/Campaign.hpp"
#include "controller/ExperimentData.hpp"
#include "coolchecksum.pb.h"
class CoolChecksumExperimentData : public fi::ExperimentData {
class CoolChecksumExperimentData : public fail::ExperimentData {
public:
CoolChecksumProtoMsg msg;
CoolChecksumExperimentData() : fi::ExperimentData(&msg) {}
CoolChecksumExperimentData() : fail::ExperimentData(&msg) {}
};
class CoolChecksumCampaign : public fi::Campaign {
class CoolChecksumCampaign : public fail::Campaign {
public:
virtual bool run();
};
#endif
#endif // __COOLCAMPAIGN_HPP__

View File

@ -1,11 +1,9 @@
#include <iostream>
#include "util/Logger.hpp"
#include "experiment.hpp"
#include "experimentInfo.hpp"
#include "campaign.hpp"
#include "SAL/SALConfig.hpp"
#include "SAL/SALInst.hpp"
#include "SAL/Memory.hpp"
@ -19,7 +17,8 @@
#include "coolchecksum.pb.h"
using std::endl;
using namespace std;
using namespace fail;
// Check if configuration dependencies are satisfied:
#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \
@ -31,24 +30,24 @@ using std::endl;
bool CoolChecksumExperiment::run()
{
Logger log("CoolChecksum", false);
fi::BPSingleEvent bp;
BPSingleEvent bp;
log << "startup" << endl;
#if 0
#if 1
// STEP 1: run until interesting function starts, and save state
bp.setWatchInstructionPointer(COOL_ECC_FUNC_ENTRY);
sal::simulator.addEventAndWait(&bp);
simulator.addEventAndWait(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer() << " or " << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
log << "error_corrected = " << std::dec << ((int)sal::simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED)) << endl;
sal::simulator.save("coolecc.state");
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or " << simulator.getRegisterManager().getInstructionPointer() << endl;
log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED)) << endl;
simulator.save("coolecc.state");
#elif 0
// STEP 2: determine # instructions from start to end
log << "restoring state" << endl;
sal::simulator.restore("coolecc.state");
log << "EIP = " << std::hex << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
simulator.restore("coolecc.state");
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
#if COOL_FAULTSPACE_PRUNING
// STEP 2.5: Additionally do a golden run with memory access tracing
@ -62,33 +61,33 @@ bool CoolChecksumExperiment::run()
tp.restrictMemoryAddresses(&mm);
// record trace
std::ofstream of("trace.pb");
ofstream of("trace.pb");
tp.setTraceFile(&of);
// this must be done *after* configuring the plugin:
sal::simulator.addFlow(&tp);
simulator.addFlow(&tp);
#endif
// make sure the timer interrupt doesn't disturb us
sal::simulator.addSuppressedInterrupt(0);
simulator.addSuppressedInterrupt(0);
int count;
bp.setWatchInstructionPointer(fi::ANY_ADDR);
bp.setWatchInstructionPointer(ANY_ADDR);
for (count = 0; bp.getTriggerInstructionPointer() != COOL_ECC_CALCDONE; ++count) {
sal::simulator.addEventAndWait(&bp);
// log << "EIP = " << std::hex << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
simulator.addEventAndWait(&bp);
// log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
}
log << "test function calculation position reached after " << std::dec << count << " instructions" << endl;
sal::Register* reg = sal::simulator.getRegisterManager().getRegister(sal::RID_CDX);
log << std::dec << reg->getName() << " = " << reg->getData() << endl;
log << "test function calculation position reached after " << dec << count << " instructions" << endl;
Register* reg = simulator.getRegisterManager().getRegister(RID_CDX);
log << dec << reg->getName() << " = " << reg->getData() << endl;
#if COOL_FAULTSPACE_PRUNING
sal::simulator.removeFlow(&tp);
simulator.removeFlow(&tp);
// serialize trace to file
if (of.fail()) {
log << "failed to write trace.pb" << endl;
sal::simulator.clearEvents(this);
simulator.clearEvents(this);
return false;
}
of.close();
@ -102,14 +101,14 @@ bool CoolChecksumExperiment::run()
// STEP 3: The actual experiment.
log << "restoring state" << endl;
sal::simulator.restore("coolecc.state");
simulator.restore("coolecc.state");
log << "asking job server for experiment parameters" << endl;
CoolChecksumExperimentData param;
if (!m_jc.getParam(param)) {
log << "Dying." << endl;
// communicate that we were told to die
sal::simulator.terminate(1);
simulator.terminate(1);
}
int id = param.getWorkloadID();
int instr_offset = param.msg.instr_offset();
@ -119,28 +118,28 @@ bool CoolChecksumExperiment::run()
// FIXME could be improved (especially for backends supporting
// breakpoints natively) by utilizing a previously recorded instruction
// trace
bp.setWatchInstructionPointer(fi::ANY_ADDR);
bp.setWatchInstructionPointer(ANY_ADDR);
for (int count = 0; count < instr_offset; ++count) {
sal::simulator.addEventAndWait(&bp);
simulator.addEventAndWait(&bp);
}
// inject
sal::guest_address_t inject_addr = COOL_ECC_OBJUNDERTEST + bit_offset / 8;
sal::MemoryManager& mm = sal::simulator.getMemoryManager();
sal::byte_t data = mm.getByte(inject_addr);
sal::byte_t newdata = data ^ (1 << (bit_offset % 8));
guest_address_t inject_addr = COOL_ECC_OBJUNDERTEST + bit_offset / 8;
MemoryManager& mm = simulator.getMemoryManager();
byte_t data = mm.getByte(inject_addr);
byte_t newdata = data ^ (1 << (bit_offset % 8));
mm.setByte(inject_addr, newdata);
// note at what IP we did it
int32_t injection_ip = sal::simulator.getRegisterManager().getInstructionPointer();
int32_t injection_ip = simulator.getRegisterManager().getInstructionPointer();
param.msg.set_injection_ip(injection_ip);
log << "inject @ ip " << injection_ip
<< " (offset " << std::dec << instr_offset << ")"
<< " (offset " << dec << instr_offset << ")"
<< " bit " << bit_offset << ": 0x"
<< std::hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
<< hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
// sanity check (only works if we're working with an instruction trace)
if (param.msg.has_instr_address() &&
injection_ip != param.msg.instr_address()) {
std::stringstream ss;
stringstream ss;
ss << "SANITY CHECK FAILED: " << injection_ip
<< " != " << param.msg.instr_address() << endl;
log << ss.str();
@ -148,55 +147,55 @@ bool CoolChecksumExperiment::run()
param.msg.set_resultdata(injection_ip);
param.msg.set_details(ss.str());
sal::simulator.clearEvents();
simulator.clearEvents();
m_jc.sendResult(param);
continue;
}
// aftermath
fi::BPSingleEvent ev_done(COOL_ECC_CALCDONE);
sal::simulator.addEvent(&ev_done);
fi::BPSingleEvent ev_timeout(fi::ANY_ADDR);
BPSingleEvent ev_done(COOL_ECC_CALCDONE);
simulator.addEvent(&ev_done);
BPSingleEvent ev_timeout(ANY_ADDR);
ev_timeout.setCounter(COOL_ECC_NUMINSTR + 3000);
sal::simulator.addEvent(&ev_timeout);
fi::TrapEvent ev_trap(fi::ANY_TRAP);
sal::simulator.addEvent(&ev_trap);
simulator.addEvent(&ev_timeout);
TrapEvent ev_trap(ANY_TRAP);
simulator.addEvent(&ev_trap);
fi::BaseEvent* ev = sal::simulator.waitAny();
BaseEvent* ev = simulator.waitAny();
if (ev == &ev_done) {
sal::Register* pRegRes = sal::simulator.getRegisterManager().getRegister(sal::RID_CDX);
Register* pRegRes = simulator.getRegisterManager().getRegister(RID_CDX);
int32_t data = pRegRes->getData();
log << std::dec << "Result " << pRegRes->getName() << " = " << data << endl;
log << dec << "Result " << pRegRes->getName() << " = " << data << endl;
param.msg.set_resulttype(param.msg.CALCDONE);
param.msg.set_resultdata(data);
} else if (ev == &ev_timeout) {
log << std::dec << "Result TIMEOUT" << endl;
log << dec << "Result TIMEOUT" << endl;
param.msg.set_resulttype(param.msg.TIMEOUT);
param.msg.set_resultdata(sal::simulator.getRegisterManager().getInstructionPointer());
param.msg.set_resultdata(simulator.getRegisterManager().getInstructionPointer());
} else if (ev == &ev_trap) {
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
param.msg.set_resulttype(param.msg.TRAP);
param.msg.set_resultdata(sal::simulator.getRegisterManager().getInstructionPointer());
param.msg.set_resultdata(simulator.getRegisterManager().getInstructionPointer());
} else {
log << std::dec << "Result WTF?" << endl;
log << dec << "Result WTF?" << endl;
param.msg.set_resulttype(param.msg.UNKNOWN);
param.msg.set_resultdata(sal::simulator.getRegisterManager().getInstructionPointer());
param.msg.set_resultdata(simulator.getRegisterManager().getInstructionPointer());
std::stringstream ss;
ss << "eventid " << ev << " EIP " << sal::simulator.getRegisterManager().getInstructionPointer();
stringstream ss;
ss << "eventid " << ev << " EIP " << simulator.getRegisterManager().getInstructionPointer();
param.msg.set_details(ss.str());
}
sal::simulator.clearEvents();
int32_t error_corrected = sal::simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED);
simulator.clearEvents();
int32_t error_corrected = simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED);
param.msg.set_error_corrected(error_corrected);
m_jc.sendResult(param);
}
// we do not want the simulator to continue running, especially for
// headless and distributed experiments
sal::simulator.terminate();
simulator.terminate();
#endif
// simulator continues to run
sal::simulator.clearEvents(this);
simulator.clearEvents(this);
return true;
}

View File

@ -1,14 +1,14 @@
#ifndef __COOLEXPERIMENT_HPP__
#define __COOLEXPERIMENT_HPP__
#define __COOLEXPERIMENT_HPP__
#include "controller/ExperimentFlow.hpp"
#include "jobserver/JobClient.hpp"
class CoolChecksumExperiment : public fi::ExperimentFlow {
fi::JobClient m_jc;
class CoolChecksumExperiment : public fail::ExperimentFlow {
fail::JobClient m_jc;
public:
CoolChecksumExperiment() : m_jc("ios.cs.tu-dortmund.de") {}
bool run();
};
#endif
#endif // __COOLEXPERIMENT_HPP__

View File

@ -1,5 +1,5 @@
#ifndef __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
#define COOL_FAULTSPACE_PRUNING 0
@ -37,4 +37,4 @@
#endif
#endif
#endif // __EXPERIMENT_INFO_HPP__

View File

@ -7,7 +7,7 @@
int main(int argc, char **argv)
{
CoolChecksumCampaign c;
if (fi::campaignmanager.runCampaign(&c)) {
if (fail::campaignmanager.runCampaign(&c)) {
return 0;
} else {
return 1;

View File

@ -1,9 +1,17 @@
/**
* \brief This experiment demonstrates the fireInterrupt feature.
*
* The keyboard-interrupts are disabled. So nothing happens if you press a button
* on keyboard. Only the pressed button will be stored in keyboard-buffer. With
* the fireInterrupt feature keyboard-interrupts are generated manually. The result
* is that the keyboard interrupts will be compensated manually. bootdisk.img can
* be used as example image (Turbo-Pacman :-) ).
*/
#include <iostream>
#include <unistd.h>
#include "experiment.hpp"
#include "SAL/SALInst.hpp"
#include "SAL/bochs/BochsRegister.hpp"
#include "controller/Event.hpp"
#include "util/Logger.hpp"
#include "config/FailConfig.hpp"
@ -13,35 +21,27 @@
#error This experiment needs: breakpoints, disabled keyboard interrupts and fire interrupts. Enable these in the configuration.
#endif
/* This experiment demonstrates the fireInterrupt feature.
* The keyboard-interrupts are disabled. So nothing happens if you press a button on keyboard.
* Only the pressed button will be stored in keyboard-buffer.
* With the fireInterrupt feature keyboard-interrupts are generated manually.
* The result is that the keyboard interrupts will be compensated manually.
* bootdisk.img can be used as example image. (turbo-pacman :) )
*/
using std::endl;
using namespace std;
using namespace fail;
bool fireinterruptExperiment::run()
{
Logger log("FireInterrupt", false);
log << "experiment start" << endl;
#if 1
while(1){
while (true) {
int j = 0;
for(j=0 ; j<=100 ; j++){
fi::BPSingleEvent mainbp(0x1045f5);
sal::simulator.addEventAndWait(&mainbp);
for (j = 0; j <= 100; j++) {
BPSingleEvent mainbp(0x1045f5);
simulator.addEventAndWait(&mainbp);
}
sal::simulator.fireInterrupt(1);
simulator.fireInterrupt(1);
}
#elif 1
sal::simulator.dbgEnableInstrPtrOutput(500);
simulator.dbgEnableInstrPtrOutput(500);
#endif
sal::simulator.clearEvents(this);
simulator.clearEvents(this);
return true;
}

View File

@ -3,11 +3,10 @@
#include "controller/ExperimentFlow.hpp"
class fireinterruptExperiment : public fi::ExperimentFlow
class fireinterruptExperiment : public fail::ExperimentFlow
{
public:
fireinterruptExperiment() { }
bool run();
};

View File

@ -14,7 +14,8 @@
#error This experiment needs: breakpoints, save, and restore. Enable these in the configuration.
#endif
using std::endl;
using namespace std;
using namespace fail;
bool hscsimpleExperiment::run()
{
@ -24,31 +25,31 @@ bool hscsimpleExperiment::run()
// do funny things here...
#if 1
// STEP 1
fi::BPSingleEvent mainbp(0x00003c34);
sal::simulator.addEventAndWait(&mainbp);
BPSingleEvent mainbp(0x00003c34);
simulator.addEventAndWait(&mainbp);
log << "breakpoint reached, saving" << endl;
sal::simulator.save("hello.state");
simulator.save("hello.state");
#elif 0
// STEP 2
log << "restoring ..." << endl;
sal::simulator.restore("hello.state");
simulator.restore("hello.state");
log << "restored!" << endl;
log << "waiting for last square() instruction" << endl;
fi::BPSingleEvent breakpoint(0x3c9e); // square(x) ret instruction
sal::simulator.addEventAndWait(&breakpoint);
BPSingleEvent breakpoint(0x3c9e); // square(x) ret instruction
simulator.addEventAndWait(&breakpoint);
log << "injecting hellish fault" << endl;
// RID_CAX is the RAX register in 64 bit mode and EAX in 32 bit mode:
sal::simulator.getRegisterManager().getRegister(sal::RID_CAX)->setData(666);
simulator.getRegisterManager().getRegister(RID_CAX)->setData(666);
log << "waiting for last main() instruction" << endl;
breakpoint.setWatchInstructionPointer(0x3c92);
sal::simulator.addEventAndWait(&breakpoint);
simulator.addEventAndWait(&breakpoint);
log << "reached" << endl;
sal::simulator.addEventAndWait(&breakpoint);
simulator.addEventAndWait(&breakpoint);
#endif
sal::simulator.clearEvents(this);
simulator.clearEvents(this);
return true;
}

View File

@ -3,7 +3,7 @@
#include "controller/ExperimentFlow.hpp"
class hscsimpleExperiment : public fi::ExperimentFlow
class hscsimpleExperiment : public fail::ExperimentFlow
{
public:
hscsimpleExperiment() { }

View File

@ -11,8 +11,8 @@
aspect @EXPERIMENT_TYPE@ExperimentHook {
@EXPERIMENT_TYPE@ experiment;
advice execution ("void sal::SimulatorController::initExperiments()") : after () {
sal::simulator.addFlow(&experiment);
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
fail::simulator.addFlow(&experiment);
}
};

View File

@ -6,8 +6,8 @@
#include "util/Logger.hpp"
#include "SAL/SALConfig.hpp"
using namespace fi;
using std::endl;
using namespace std;
using namespace fail;
char const * const results_csv = "l4sys.csv";
@ -39,23 +39,23 @@ bool L4SysCampaign::run()
d->msg.set_bit_offset(bit_offset);
d->msg.set_bit_offset(0);
fi::campaignmanager.addParam(d);
campaignmanager.addParam(d);
++count;
}
}
fi::campaignmanager.noMoreParameters();
campaignmanager.noMoreParameters();
log << "done enqueueing parameter sets (" << count << ")." << endl;
// collect results
L4SysExperimentData *res;
int rescount = 0;
results << "injection_ip,instr_offset,injection_bit,resulttype,resultdata,output,details" << endl;
while ((res = static_cast<L4SysExperimentData *>(fi::campaignmanager.getDone()))) {
while ((res = static_cast<L4SysExperimentData *>(campaignmanager.getDone()))) {
rescount++;
results << std::hex
results << hex
<< res->msg.injection_ip() << ","
<< std::dec << res->msg.instr_offset() << ","
<< dec << res->msg.instr_offset() << ","
<< res->msg.bit_offset() << ","
<< res->msg.resulttype() << ","
<< res->msg.resultdata();

View File

@ -1,20 +1,19 @@
#ifndef __COOLCAMPAIGN_HPP__
#define __COOLCAMPAIGN_HPP__
#ifndef __L4SYS_CAMPAIGN_HPP__
#define __L4SYS_CAMPAIGN_HPP__
#include "controller/Campaign.hpp"
#include "controller/ExperimentData.hpp"
#include "l4sys.pb.h"
class L4SysExperimentData : public fi::ExperimentData {
class L4SysExperimentData : public fail::ExperimentData {
public:
L4SysProtoMsg msg;
L4SysExperimentData() : fi::ExperimentData(&msg) {}
L4SysExperimentData() : fail::ExperimentData(&msg) {}
};
class L4SysCampaign : public fi::Campaign {
class L4SysCampaign : public fail::Campaign {
public:
virtual bool run();
};
#endif
#endif // __L4SYS_CAMPAIGN_HPP__

View File

@ -20,7 +20,8 @@
#include "l4sys.pb.h"
using std::endl;
using namespace std;
using namespace fail;
// Check if configuration dependencies are satisfied:
#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \
@ -31,17 +32,18 @@ using std::endl;
save, and restore. Enable these in the configuration.
#endif
char const * const state_folder = "l4sys.state";
char const * const state_folder = "l4sys.state";
char const * const instr_list_fn = "ip.list";
char const * const golden_run_fn = "golden.out";
sal::address_t const aspace = 0x01e00000;
std::string output;
std::vector<sal::address_t> instr_list;
std::string golden_run;
address_t const aspace = 0x01e00000;
string output;
vector<address_t> instr_list;
string golden_run;
//the program needs to run 5 times without a fault
const unsigned times_run = 5;
std::string L4SysExperiment::sanitised(std::string in_str) {
string L4SysExperiment::sanitised(string in_str)
{
string result;
result.reserve(in_str.size());
for (string::iterator it = in_str.begin(); it != in_str.end(); it++) {
@ -57,15 +59,16 @@ std::string L4SysExperiment::sanitised(std::string in_str) {
return result;
}
fi::BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output) {
fi::IOPortEvent ev_ioport(0x3F8, true);
fi::BaseEvent* ev = NULL;
BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output)
{
IOPortEvent ev_ioport(0x3F8, true);
BaseEvent* ev = NULL;
if (clear_output)
output.clear();
while (true) {
sal::simulator.addEvent(&ev_ioport);
ev = sal::simulator.waitAny();
sal::simulator.removeEvent(&ev_ioport);
simulator.addEvent(&ev_ioport);
ev = simulator.waitAny();
simulator.removeEvent(&ev_ioport);
if (ev == &ev_ioport) {
output += ev_ioport.getData();
} else {
@ -75,9 +78,10 @@ fi::BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output) {
return ev;
}
bool L4SysExperiment::run() {
bool L4SysExperiment::run()
{
Logger log("L4Sys", false);
fi::BPSingleEvent bp(0, aspace);
BPSingleEvent bp(0, aspace);
log << "startup" << endl;
@ -87,46 +91,46 @@ bool L4SysExperiment::run() {
// STEP 1: run until interesting function starts, and save state
if (stat(state_folder, &teststruct) == -1) {
bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
sal::simulator.addEventAndWait(&bp);
simulator.addEventAndWait(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer()
log << "EIP = " << hex << bp.getTriggerInstructionPointer()
<< " or "
<< sal::simulator.getRegisterManager().getInstructionPointer()
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
sal::simulator.save(state_folder);
simulator.save(state_folder);
}
// STEP 2: determine instructions executed
if (stat(instr_list_fn, &teststruct) == -1) {
log << "restoring state" << endl;
sal::simulator.restore(state_folder);
log << "EIP = " << std::hex
<< sal::simulator.getRegisterManager().getInstructionPointer()
simulator.restore(state_folder);
log << "EIP = " << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
// make sure the timer interrupt doesn't disturb us
sal::simulator.addSuppressedInterrupt(32);
simulator.addSuppressedInterrupt(32);
std::ofstream instr_list_file(instr_list_fn);
instr_list_file << std::hex;
bp.setWatchInstructionPointer(fi::ANY_ADDR);
ofstream instr_list_file(instr_list_fn);
instr_list_file << hex;
bp.setWatchInstructionPointer(ANY_ADDR);
while (bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) {
sal::simulator.addEventAndWait(&bp);
simulator.addEventAndWait(&bp);
//short sanity check
sal::address_t curr_instr = bp.getTriggerInstructionPointer();
address_t curr_instr = bp.getTriggerInstructionPointer();
assert(
curr_instr == sal::simulator.getRegisterManager().getInstructionPointer());
curr_instr == simulator.getRegisterManager().getInstructionPointer());
instr_list.push_back(curr_instr);
instr_list_file << curr_instr << endl;
}
log << "saving instructions triggered during normal execution" << endl;
instr_list_file.close();
} else {
std::ifstream instr_list_file(instr_list_fn);
instr_list_file >> std::hex;
ifstream instr_list_file(instr_list_fn);
instr_list_file >> hex;
while (!instr_list_file.eof()) {
sal::address_t curr_instr;
address_t curr_instr;
instr_list_file >> curr_instr;
instr_list.push_back(curr_instr);
}
@ -136,19 +140,19 @@ bool L4SysExperiment::run() {
// STEP 3: determine the output of a "golden run"
if (stat(golden_run_fn, &teststruct) == -1) {
log << "restoring state" << endl;
sal::simulator.restore(state_folder);
log << "EIP = " << std::hex
<< sal::simulator.getRegisterManager().getInstructionPointer()
simulator.restore(state_folder);
log << "EIP = " << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
// make sure the timer interrupt doesn't disturb us
sal::simulator.addSuppressedInterrupt(32);
simulator.addSuppressedInterrupt(32);
std::ofstream golden_run_file(golden_run_fn);
ofstream golden_run_file(golden_run_fn);
bp.setWatchInstructionPointer(L4SYS_FUNC_EXIT);
bp.setCounter(times_run);
sal::simulator.addEvent(&bp);
fi::BaseEvent* ev = waitIOOrOther(true);
simulator.addEvent(&bp);
BaseEvent* ev = waitIOOrOther(true);
if (ev == &bp) {
golden_run.assign(output.c_str());
golden_run_file << output.c_str();
@ -158,23 +162,23 @@ bool L4SysExperiment::run() {
<< "Obviously, there is some trouble with the events registered - aborting simulation!"
<< endl;
golden_run_file.close();
sal::simulator.terminate(10);
simulator.terminate(10);
}
sal::simulator.clearEvents();
simulator.clearEvents();
bp.setCounter(1);
log << "saving output generated during normal execution" << endl;
golden_run_file.close();
} else {
std::ifstream golden_run_file(golden_run_fn);
ifstream golden_run_file(golden_run_fn);
//shamelessly copied from http://stackoverflow.com/questions/2602013/:
golden_run_file.seekg(0, std::ios::end);
golden_run_file.seekg(0, ios::end);
size_t flen = golden_run_file.tellg();
golden_run.reserve(flen);
golden_run_file.seekg(0, std::ios::beg);
golden_run_file.seekg(0, ios::beg);
golden_run.assign((std::istreambuf_iterator<char>(golden_run_file)),
std::istreambuf_iterator<char>());
golden_run.assign((istreambuf_iterator<char>(golden_run_file)),
istreambuf_iterator<char>());
golden_run_file.close();
@ -187,14 +191,14 @@ bool L4SysExperiment::run() {
// STEP 4: The actual experiment.
for (int i = 0; i < 1/*L4SYS_NUMINSTR*/; i++) {
log << "restoring state" << endl;
sal::simulator.restore(state_folder);
simulator.restore(state_folder);
log << "asking job server for experiment parameters" << endl;
L4SysExperimentData param;
if (!m_jc.getParam(param)) {
log << "Dying." << endl;
// communicate that we were told to die
sal::simulator.terminate(1);
simulator.terminate(1);
}
int id = param.getWorkloadID();
int instr_offset = param.msg.instr_offset();
@ -203,28 +207,28 @@ bool L4SysExperiment::run() {
<< bit_offset << endl;
bp.setWatchInstructionPointer(instr_list[instr_offset]);
sal::simulator.addEvent(&bp);
simulator.addEvent(&bp);
//and log the output
waitIOOrOther(true);
// inject
sal::RegisterManager& rm = sal::simulator.getRegisterManager();
sal::Register *ebx = rm.getRegister(sal::RID_EBX);
sal::regdata_t data = ebx->getData();
sal::regdata_t newdata = data ^ (1 << bit_offset);
RegisterManager& rm = simulator.getRegisterManager();
Register *ebx = rm.getRegister(RID_EBX);
regdata_t data = ebx->getData();
regdata_t newdata = data ^ (1 << bit_offset);
ebx->setData(newdata);
// note at what IP we did it
sal::address_t injection_ip =
sal::simulator.getRegisterManager().getInstructionPointer();
address_t injection_ip =
simulator.getRegisterManager().getInstructionPointer();
param.msg.set_injection_ip(injection_ip);
log << "inject @ ip " << injection_ip << " (offset " << std::dec
log << "inject @ ip " << injection_ip << " (offset " << dec
<< instr_offset << ")" << " bit " << bit_offset << ": 0x"
<< std::hex << ((int) data) << " -> 0x" << ((int) newdata)
<< hex << ((int) data) << " -> 0x" << ((int) newdata)
<< endl;
// sanity check (only works if we're working with an instruction trace)
if (injection_ip != instr_list[instr_offset]) {
std::stringstream ss;
stringstream ss;
ss << "SANITY CHECK FAILED: " << injection_ip << " != "
<< instr_list[instr_offset] << endl;
log << ss.str();
@ -232,28 +236,28 @@ bool L4SysExperiment::run() {
param.msg.set_resultdata(injection_ip);
param.msg.set_details(ss.str());
sal::simulator.clearEvents();
simulator.clearEvents();
m_jc.sendResult(param);
continue;
}
// aftermath
fi::BPSingleEvent ev_done(L4SYS_FUNC_EXIT, aspace);
BPSingleEvent ev_done(L4SYS_FUNC_EXIT, aspace);
ev_done.setCounter(times_run);
sal::simulator.addEvent(&ev_done);
simulator.addEvent(&ev_done);
const unsigned instr_run = times_run * L4SYS_NUMINSTR;
fi::BPSingleEvent ev_timeout(fi::ANY_ADDR, aspace);
BPSingleEvent ev_timeout(ANY_ADDR, aspace);
ev_timeout.setCounter(instr_run + 3000);
sal::simulator.addEvent(&ev_timeout);
fi::TrapEvent ev_trap(fi::ANY_TRAP);
sal::simulator.addEvent(&ev_trap);
fi::InterruptEvent ev_intr(fi::ANY_INTERRUPT);
simulator.addEvent(&ev_timeout);
TrapEvent ev_trap(ANY_TRAP);
simulator.addEvent(&ev_trap);
InterruptEvent ev_intr(ANY_INTERRUPT);
//ten times as many interrupts as instructions justify an exception
ev_intr.setCounter(instr_run * 10);
sal::simulator.addEvent(&ev_intr);
simulator.addEvent(&ev_intr);
//do not discard output recorded so far
fi::BaseEvent *ev = waitIOOrOther(false);
BaseEvent *ev = waitIOOrOther(false);
/* copying a string object that contains control sequences
* unfortunately does not work with the library I am using,
@ -262,53 +266,53 @@ bool L4SysExperiment::run() {
*/
if (ev == &ev_done) {
if (strcmp(output.c_str(), golden_run.c_str()) == 0) {
log << std::dec << "Result DONE" << endl;
log << dec << "Result DONE" << endl;
param.msg.set_resulttype(param.msg.DONE);
} else {
log << std::dec << "Result WRONG" << endl;
log << dec << "Result WRONG" << endl;
param.msg.set_resulttype(param.msg.WRONG);
param.msg.set_output(sanitised(output.c_str()));
}
} else if (ev == &ev_timeout) {
log << std::dec << "Result TIMEOUT" << endl;
log << dec << "Result TIMEOUT" << endl;
param.msg.set_resulttype(param.msg.TIMEOUT);
param.msg.set_resultdata(
sal::simulator.getRegisterManager().getInstructionPointer());
simulator.getRegisterManager().getInstructionPointer());
param.msg.set_output(sanitised(output.c_str()));
} else if (ev == &ev_trap) {
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber()
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber()
<< endl;
param.msg.set_resulttype(param.msg.TRAP);
param.msg.set_resultdata(
sal::simulator.getRegisterManager().getInstructionPointer());
simulator.getRegisterManager().getInstructionPointer());
param.msg.set_output(sanitised(output.c_str()));
} else if (ev == &ev_intr) {
log << std::hex << "Result INT FLOOD; Last INT #:"
log << hex << "Result INT FLOOD; Last INT #:"
<< ev_intr.getTriggerNumber() << endl;
param.msg.set_resulttype(param.msg.INTR);
param.msg.set_resultdata(
sal::simulator.getRegisterManager().getInstructionPointer());
simulator.getRegisterManager().getInstructionPointer());
param.msg.set_output(sanitised(output.c_str()));
} else {
log << std::dec << "Result WTF?" << endl;
log << dec << "Result WTF?" << endl;
param.msg.set_resulttype(param.msg.UNKNOWN);
param.msg.set_resultdata(
sal::simulator.getRegisterManager().getInstructionPointer());
simulator.getRegisterManager().getInstructionPointer());
param.msg.set_output(sanitised(output.c_str()));
std::stringstream ss;
stringstream ss;
ss << "eventid " << ev << " EIP "
<< sal::simulator.getRegisterManager().getInstructionPointer()
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
param.msg.set_details(ss.str());
}
sal::simulator.clearEvents();
simulator.clearEvents();
m_jc.sendResult(param);
}
#ifdef HEADLESS_EXPERIMENT
sal::simulator.terminate(0);
simulator.terminate(0);
#endif
// experiment successfully conducted
return true;

View File

@ -1,17 +1,23 @@
#ifndef __COOLEXPERIMENT_HPP__
#define __COOLEXPERIMENT_HPP__
#ifndef __L4SYS_EXPERIMENT_HPP__
#define __L4SYS_EXPERIMENT_HPP__
#include <string>
#include "controller/ExperimentFlow.hpp"
#include "jobserver/JobClient.hpp"
class L4SysExperiment : public fi::ExperimentFlow {
fi::JobClient m_jc;
class L4SysExperiment : public fail::ExperimentFlow {
fail::JobClient m_jc;
public:
L4SysExperiment() : m_jc("localhost") {}
bool run();
private:
// NOTE: It's good practise to use "const std::string&" as parameter type.
// Additionaly, if you don't need the return value to be copied,
// return a (const) reference to a class member or a static string-
// object.
std::string sanitised(std::string in_str);
fi::BaseEvent* waitIOOrOther(bool clear_output);
fail::BaseEvent* waitIOOrOther(bool clear_output);
};
#endif
#endif // __L4SYS_EXPERIMENT_HPP__

View File

@ -1,5 +1,5 @@
#ifndef __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
// FIXME autogenerate this
@ -9,4 +9,4 @@
//#define HEADLESS_EXPERIMENT
#define PREPARE_EXPERIMENT
#endif
#endif // __EXPERIMENT_INFO_HPP__

View File

@ -7,7 +7,7 @@
int main(int argc, char **argv)
{
L4SysCampaign c;
if (fi::campaignmanager.runCampaign(&c)) {
if (fail::campaignmanager.runCampaign(&c)) {
return 0;
} else {
return 1;

View File

@ -13,10 +13,10 @@
#include "plugins/tracing/TracingPlugin.hpp"
using namespace fi;
using std::endl;
using namespace std;
using namespace fail;
char const * const trace_filename = "trace.pb";
char const * const trace_filename = "trace.pb";
char const * const results_filename = "weathermonitor.csv";
// equivalence class type: addr, [i1, i2]
@ -24,9 +24,9 @@ char const * const results_filename = "weathermonitor.csv";
// [i1, i2]: interval of instruction numbers, counted from experiment
// begin
struct equivalence_class {
sal::address_t data_address;
address_t data_address;
int instr1, instr2;
sal::address_t instr2_absolute;
address_t instr2_absolute;
};
bool WeathermonitorCampaign::run()
@ -57,15 +57,15 @@ bool WeathermonitorCampaign::run()
// set of equivalence classes that need one (rather: eight, one for
// each bit in that byte) experiment to determine them all
std::vector<equivalence_class> ecs_need_experiment;
vector<equivalence_class> ecs_need_experiment;
// set of equivalence classes that need no experiment, because we know
// they'd be identical to the golden run
std::vector<equivalence_class> ecs_no_effect;
vector<equivalence_class> ecs_no_effect;
equivalence_class current_ec;
// map for efficient access when results come in
std::map<WeathermonitorExperimentData *, unsigned> experiment_ecs;
map<WeathermonitorExperimentData *, unsigned> experiment_ecs;
// experiment count
int count = 0;
@ -73,11 +73,11 @@ bool WeathermonitorCampaign::run()
// -> one "open" EC for every address
// for every injection address ...
for (MemoryMap::iterator it = mm.begin(); it != mm.end(); ++it) {
std::cerr << ".";
sal::address_t data_address = *it;
cerr << ".";
address_t data_address = *it;
current_ec.instr1 = 0;
int instr = 0;
sal::address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
Trace_Event ev;
ps.reset();
@ -131,7 +131,7 @@ bool WeathermonitorCampaign::run()
// store index into ecs_need_experiment
experiment_ecs[d] = ecs_need_experiment.size() - 1;
fi::campaignmanager.addParam(d);
campaignmanager.addParam(d);
++count;
} else if (ev.accesstype() == ev.WRITE) {
// a sequence ending with WRITE: an
@ -181,11 +181,11 @@ bool WeathermonitorCampaign::run()
// store index into ecs_need_experiment
experiment_ecs[d] = ecs_need_experiment.size() - 1;
fi::campaignmanager.addParam(d);
campaignmanager.addParam(d);
++count;
}
fi::campaignmanager.noMoreParameters();
campaignmanager.noMoreParameters();
log << "done enqueueing parameter sets (" << count << ")." << endl;
log << "equivalence classes generated:"
@ -194,11 +194,11 @@ bool WeathermonitorCampaign::run()
// statistics
unsigned long num_dumb_experiments = 0;
for (std::vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
for (vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
it != ecs_need_experiment.end(); ++it) {
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
}
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
it != ecs_no_effect.end(); ++it) {
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
}
@ -209,7 +209,7 @@ bool WeathermonitorCampaign::run()
results << "ec_instr1\tec_instr2\tec_instr2_absolute\tec_data_address\tbitnr\tbit_width\tresulttype\tlatest_ip\titer1\titer2\tdetails" << endl;
// store no-effect "experiment" results
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
it != ecs_no_effect.end(); ++it) {
results
<< (*it).instr1 << "\t"
@ -227,10 +227,10 @@ bool WeathermonitorCampaign::run()
// collect results
WeathermonitorExperimentData *res;
int rescount = 0;
while ((res = static_cast<WeathermonitorExperimentData *>(fi::campaignmanager.getDone()))) {
while ((res = static_cast<WeathermonitorExperimentData *>(campaignmanager.getDone()))) {
rescount++;
std::map<WeathermonitorExperimentData *, unsigned>::iterator it =
map<WeathermonitorExperimentData *, unsigned>::iterator it =
experiment_ecs.find(res);
if (it == experiment_ecs.end()) {
results << "WTF, didn't find res!" << endl;

View File

@ -1,19 +1,19 @@
#ifndef __WEATHERMONITOR_CAMPAIGN_HPP__
#define __WEATHERMONITOR_CAMPAIGN_HPP__
#define __WEATHERMONITOR_CAMPAIGN_HPP__
#include "controller/Campaign.hpp"
#include "controller/ExperimentData.hpp"
#include "weathermonitor.pb.h"
class WeathermonitorExperimentData : public fi::ExperimentData {
class WeathermonitorExperimentData : public fail::ExperimentData {
public:
WeathermonitorProtoMsg msg;
WeathermonitorExperimentData() : fi::ExperimentData(&msg) {}
WeathermonitorExperimentData() : fail::ExperimentData(&msg) {}
};
class WeathermonitorCampaign : public fi::Campaign {
class WeathermonitorCampaign : public fail::Campaign {
public:
virtual bool run();
};
#endif
#endif // __WEATHERMONITOR_CAMPAIGN_HPP__

View File

@ -23,12 +23,12 @@
#define LOCAL 0
using std::endl;
using namespace std;
using namespace fail;
// Check if configuration dependencies are satisfied:
#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \
!defined(CONFIG_SR_SAVE) || !defined(CONFIG_EVENT_TRAP)
#error This experiment needs: breakpoints, traps, save, and restore. Enable these in the configuration.
#endif
@ -36,32 +36,32 @@ bool WeathermonitorExperiment::run()
{
char const *statename = "bochs.state";
Logger log("Weathermonitor", false);
fi::BPSingleEvent bp;
BPSingleEvent bp;
log << "startup" << endl;
#if 1
// STEP 0: record memory map with vptr addresses
fi::GuestEvent g;
GuestEvent g;
while (true) {
sal::simulator.addEventAndWait(&g);
std::cout << g.getData() << std::flush;
simulator.addEventAndWait(&g);
cout << g.getData() << flush;
}
#elif 0
// STEP 1: run until interesting function starts, and save state
bp.setWatchInstructionPointer(WEATHER_FUNC_MAIN);
sal::simulator.addEventAndWait(&bp);
simulator.addEventAndWait(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer() << endl;
sal::simulator.save(statename);
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
simulator.save(statename);
assert(bp.getTriggerInstructionPointer() == WEATHER_FUNC_MAIN);
assert(sal::simulator.getRegisterManager().getInstructionPointer() == WEATHER_FUNC_MAIN);
assert(simulator.getRegisterManager().getInstructionPointer() == WEATHER_FUNC_MAIN);
// STEP 2: record trace for fault-space pruning
log << "restoring state" << endl;
sal::simulator.restore(statename);
log << "EIP = " << std::hex << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
assert(sal::simulator.getRegisterManager().getInstructionPointer() == WEATHER_FUNC_MAIN);
simulator.restore(statename);
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
assert(simulator.getRegisterManager().getInstructionPointer() == WEATHER_FUNC_MAIN);
log << "enabling tracing" << endl;
TracingPlugin tp;
@ -76,35 +76,35 @@ bool WeathermonitorExperiment::run()
// record trace
char const *tracefile = "trace.pb";
std::ofstream of(tracefile);
ofstream of(tracefile);
tp.setTraceFile(&of);
// this must be done *after* configuring the plugin:
sal::simulator.addFlow(&tp);
simulator.addFlow(&tp);
// trace WEATHER_NUMITER_TRACING measurement loop iterations
bp.setWatchInstructionPointer(WEATHER_FUNC_WAIT_END);
bp.setCounter(WEATHER_NUMITER_TRACING);
sal::simulator.addEvent(&bp);
fi::BPSingleEvent ev_count(fi::ANY_ADDR);
sal::simulator.addEvent(&ev_count);
simulator.addEvent(&bp);
BPSingleEvent ev_count(ANY_ADDR);
simulator.addEvent(&ev_count);
// count instructions
// FIXME add SAL functionality for this?
int instr_counter = 0;
while (sal::simulator.waitAny() == &ev_count) {
while (simulator.waitAny() == &ev_count) {
++instr_counter;
sal::simulator.addEvent(&ev_count);
simulator.addEvent(&ev_count);
}
log << std::dec << "tracing finished after " << instr_counter
log << dec << "tracing finished after " << instr_counter
<< " instructions, seeing wait_end " << WEATHER_NUMITER_TRACING << " times" << endl;
sal::simulator.removeFlow(&tp);
simulator.removeFlow(&tp);
// serialize trace to file
if (of.fail()) {
log << "failed to write " << tracefile << endl;
sal::simulator.clearEvents(this); // cleanup
simulator.clearEvents(this); // cleanup
return false;
}
of.close();
@ -113,17 +113,17 @@ bool WeathermonitorExperiment::run()
// wait another WEATHER_NUMITER_AFTER measurement loop iterations
bp.setWatchInstructionPointer(WEATHER_FUNC_WAIT_END);
bp.setCounter(WEATHER_NUMITER_AFTER);
sal::simulator.addEvent(&bp);
simulator.addEvent(&bp);
// count instructions
// FIXME add SAL functionality for this?
instr_counter = 0;
while (sal::simulator.waitAny() == &ev_count) {
while (simulator.waitAny() == &ev_count) {
++instr_counter;
sal::simulator.addEvent(&ev_count);
simulator.addEvent(&ev_count);
}
log << std::dec << "experiment finished after " << instr_counter
log << dec << "experiment finished after " << instr_counter
<< " instructions, seeing wait_end " << WEATHER_NUMITER_AFTER << " times" << endl;
#elif 0
@ -139,7 +139,7 @@ bool WeathermonitorExperiment::run()
if (!m_jc.getParam(param)) {
log << "Dying." << endl;
// communicate that we were told to die
sal::simulator.terminate(1);
simulator.terminate(1);
}
#else
// XXX debug
@ -157,62 +157,62 @@ bool WeathermonitorExperiment::run()
// 8 results in one job
WeathermonitorProtoMsg_Result *result = param.msg.add_result();
result->set_bit_offset(bit_offset);
log << std::dec << "job " << id << " instr " << instr_offset
log << dec << "job " << id << " instr " << instr_offset
<< " mem " << mem_addr << "+" << bit_offset << endl;
log << "restoring state" << endl;
sal::simulator.restore(statename);
simulator.restore(statename);
// XXX debug
/*
std::stringstream fname;
stringstream fname;
fname << "job." << ::getpid();
std::ofstream job(fname.str().c_str());
ofstream job(fname.str().c_str());
job << "job " << id << " instr " << instr_offset << " (" << param.msg.instr_address() << ") mem " << mem_addr << "+" << bit_offset << endl;
job.close();
*/
// this marks THE END
fi::BPSingleEvent ev_end(fi::ANY_ADDR);
BPSingleEvent ev_end(ANY_ADDR);
ev_end.setCounter(WEATHER_NUMINSTR_TRACING + WEATHER_NUMINSTR_AFTER);
sal::simulator.addEvent(&ev_end);
simulator.addEvent(&ev_end);
// count loop iterations by counting wait_begin() calls
// FIXME would be nice to have a callback API for this as this needs to
// be done "in parallel"
fi::BPSingleEvent ev_wait_begin(WEATHER_FUNC_WAIT_BEGIN);
sal::simulator.addEvent(&ev_wait_begin);
BPSingleEvent ev_wait_begin(WEATHER_FUNC_WAIT_BEGIN);
simulator.addEvent(&ev_wait_begin);
int count_loop_iter_before = 0;
// no need to wait if offset is 0
if (instr_offset > 0) {
// XXX could be improved with intermediate states (reducing runtime until injection)
bp.setWatchInstructionPointer(fi::ANY_ADDR);
bp.setWatchInstructionPointer(ANY_ADDR);
bp.setCounter(instr_offset);
sal::simulator.addEvent(&bp);
simulator.addEvent(&bp);
// count loop iterations until FI
while (sal::simulator.waitAny() == &ev_wait_begin) {
while (simulator.waitAny() == &ev_wait_begin) {
++count_loop_iter_before;
sal::simulator.addEvent(&ev_wait_begin);
simulator.addEvent(&ev_wait_begin);
}
}
// --- fault injection ---
sal::MemoryManager& mm = sal::simulator.getMemoryManager();
sal::byte_t data = mm.getByte(mem_addr);
sal::byte_t newdata = data ^ (1 << bit_offset);
MemoryManager& mm = simulator.getMemoryManager();
byte_t data = mm.getByte(mem_addr);
byte_t newdata = data ^ (1 << bit_offset);
mm.setByte(mem_addr, newdata);
// note at what IP we did it
int32_t injection_ip = sal::simulator.getRegisterManager().getInstructionPointer();
int32_t injection_ip = simulator.getRegisterManager().getInstructionPointer();
param.msg.set_injection_ip(injection_ip);
result->set_iter_before_fi(count_loop_iter_before);
log << "fault injected @ ip " << injection_ip
<< " 0x" << std::hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
<< " 0x" << hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
// sanity check
if (param.msg.has_instr_address() &&
injection_ip != param.msg.instr_address()) {
std::stringstream ss;
stringstream ss;
ss << "SANITY CHECK FAILED: " << injection_ip
<< " != " << param.msg.instr_address();
log << ss.str() << endl;
@ -221,7 +221,7 @@ bool WeathermonitorExperiment::run()
result->set_details(ss.str());
result->set_iter_after_fi(0);
sal::simulator.clearEvents();
simulator.clearEvents();
continue;
}
@ -239,63 +239,63 @@ bool WeathermonitorExperiment::run()
// - (XXX "sane" display?)
// catch traps as "extraordinary" ending
fi::TrapEvent ev_trap(fi::ANY_TRAP);
sal::simulator.addEvent(&ev_trap);
TrapEvent ev_trap(ANY_TRAP);
simulator.addEvent(&ev_trap);
// jump outside text segment
fi::BPRangeEvent ev_below_text(fi::ANY_ADDR, WEATHER_TEXT_START - 1);
fi::BPRangeEvent ev_beyond_text(WEATHER_TEXT_END + 1, fi::ANY_ADDR);
sal::simulator.addEvent(&ev_below_text);
sal::simulator.addEvent(&ev_beyond_text);
BPRangeEvent ev_below_text(ANY_ADDR, WEATHER_TEXT_START - 1);
BPRangeEvent ev_beyond_text(WEATHER_TEXT_END + 1, ANY_ADDR);
simulator.addEvent(&ev_below_text);
simulator.addEvent(&ev_beyond_text);
// error detected
fi::BPSingleEvent ev_detected(WEATHER_FUNC_VPTR_PANIC);
sal::simulator.addEvent(&ev_detected);
BPSingleEvent ev_detected(WEATHER_FUNC_VPTR_PANIC);
simulator.addEvent(&ev_detected);
#if LOCAL && 0
// XXX debug
log << "enabling tracing" << endl;
TracingPlugin tp;
tp.setLogIPOnly(true);
tp.setOstream(&std::cout);
tp.setOstream(&cout);
// this must be done *after* configuring the plugin:
sal::simulator.addFlow(&tp);
simulator.addFlow(&tp);
#endif
fi::BaseEvent* ev;
BaseEvent* ev;
// count loop iterations
int count_loop_iter_after = 0;
while ((ev = sal::simulator.waitAny()) == &ev_wait_begin) {
while ((ev = simulator.waitAny()) == &ev_wait_begin) {
++count_loop_iter_after;
sal::simulator.addEvent(&ev_wait_begin);
simulator.addEvent(&ev_wait_begin);
}
result->set_iter_after_fi(count_loop_iter_after);
// record latest IP regardless of result
result->set_latest_ip(sal::simulator.getRegisterManager().getInstructionPointer());
result->set_latest_ip(simulator.getRegisterManager().getInstructionPointer());
if (ev == &ev_end) {
log << "Result FINISHED (" << std::dec
log << "Result FINISHED (" << dec
<< count_loop_iter_before << "+" << count_loop_iter_after << ")" << endl;
result->set_resulttype(result->FINISHED);
} else if (ev == &ev_below_text || ev == &ev_beyond_text) {
log << "Result OUTSIDE" << endl;
result->set_resulttype(result->OUTSIDE);
} else if (ev == &ev_trap) {
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
result->set_resulttype(result->TRAP);
std::stringstream ss;
stringstream ss;
ss << ev_trap.getTriggerNumber();
result->set_details(ss.str());
} else if (ev == &ev_detected) {
log << std::dec << "Result DETECTED" << endl;
log << dec << "Result DETECTED" << endl;
result->set_resulttype(result->DETECTED);
} else {
log << "Result WTF?" << endl;
result->set_resulttype(result->UNKNOWN);
std::stringstream ss;
ss << "eventid " << ev->getId() << " EIP " << sal::simulator.getRegisterManager().getInstructionPointer();
stringstream ss;
ss << "eventid " << ev->getId() << " EIP " << simulator.getRegisterManager().getInstructionPointer();
result->set_details(ss.str());
}
}
@ -311,5 +311,5 @@ bool WeathermonitorExperiment::run()
#endif
// Explicitly terminate, or the simulator will continue to run.
sal::simulator.terminate();
simulator.terminate();
}

View File

@ -1,14 +1,14 @@
#ifndef __WEATHERMONITOR_EXPERIMENT_HPP__
#define __WEATHERMONITOR_EXPERIMENT_HPP__
#define __WEATHERMONITOR_EXPERIMENT_HPP__
#include "controller/ExperimentFlow.hpp"
#include "jobserver/JobClient.hpp"
class WeathermonitorExperiment : public fi::ExperimentFlow {
fi::JobClient m_jc;
class WeathermonitorExperiment : public fail::ExperimentFlow {
fail::JobClient m_jc;
public:
WeathermonitorExperiment() : m_jc("ios.cs.tu-dortmund.de") {}
bool run();
};
#endif
#endif // __WEATHERMONITOR_EXPERIMENT_HPP__

View File

@ -7,5 +7,5 @@
int main(int argc, char **argv)
{
WeathermonitorCampaign c;
return !fi::campaignmanager.runCampaign(&c);
return !fail::campaignmanager.runCampaign(&c);
}