- introduced improved logging in RATFlip
- adapted the manual - centralised output conversion git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1988 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -20,6 +20,8 @@ set(MY_CAMPAIGN_SRCS
|
||||
UDIS86.cc
|
||||
InstructionFilter.hpp
|
||||
InstructionFilter.cc
|
||||
conversion.hpp
|
||||
conversion.cc
|
||||
)
|
||||
|
||||
#### PROTOBUFS ####
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
62c62
|
||||
< if (m_Data.getAddressSpace() == ANY_ADDR || m_Data.getAddressSpace() == address_space)
|
||||
---
|
||||
> if (m_Data.getAddressSpace() == ANY_ADDR || m_Data.getAddressSpace() == address_space) {
|
||||
63a64
|
||||
> }
|
||||
86c87,91
|
||||
< if (m_WatchInstrPtr == ANY_ADDR || m_WatchInstrPtr == pEv->getTriggerInstructionPointer())
|
||||
---
|
||||
> if (m_WatchInstrPtr == ANY_ADDR || m_WatchInstrPtr == pEv->getTriggerInstructionPointer()) {
|
||||
> address_t address_space = pEv->getAddressSpace();
|
||||
> if (address_space) {
|
||||
> fprintf(stderr, "Got a match; address space: 0x%x\n", address_space);
|
||||
> }
|
||||
87a93
|
||||
> }
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include "campaign.hpp"
|
||||
#include "experimentInfo.hpp"
|
||||
#include "conversion.hpp"
|
||||
#include "cpn/CampaignManager.hpp"
|
||||
#include "util/Logger.hpp"
|
||||
#include "sal/SALConfig.hpp"
|
||||
@ -11,10 +12,8 @@ using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
char const * const results_csv = "l4sys.csv";
|
||||
char const *l4sys_output_result_strings[] = { "Unknown", "No effect", "Incomplete execution", "Crash", "Silent data corruption", "Error" };
|
||||
char const *l4sys_output_experiment_strings[] = { "Unknown", "GPR Flip", "RAT Flip", "IDC Flip", "ALU Instr Flip" };
|
||||
char const *l4sys_output_register_strings[] = { "Unknown", "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" };
|
||||
|
||||
#if 0
|
||||
#define OUTPUT_CASE(OUTPUT) case L4SysProtoMsg::OUTPUT: return l4sys_output_result_strings[L4SysProtoMsg::OUTPUT];
|
||||
std::string L4SysCampaign::output_result(L4SysProtoMsg_ResultType res) {
|
||||
switch (res) {
|
||||
@ -56,6 +55,11 @@ std::string L4SysCampaign::output_register(L4SysProtoMsg_RegisterType res) {
|
||||
}
|
||||
}
|
||||
#undef OUTPUT_CASE
|
||||
#endif
|
||||
|
||||
extern L4SysConversion l4sysResultConversion;
|
||||
extern L4SysConversion l4sysExperimentConversion;
|
||||
extern L4SysConversion l4sysRegisterConversion;
|
||||
|
||||
bool L4SysCampaign::run() {
|
||||
Logger log("L4SysCampaign");
|
||||
@ -77,6 +81,7 @@ bool L4SysCampaign::run() {
|
||||
int count = 0;
|
||||
srand(time(NULL));
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < 20000; ++i) {
|
||||
L4SysExperimentData *d = new L4SysExperimentData;
|
||||
d->msg.set_exp_type(d->msg.GPRFLIP);
|
||||
@ -119,7 +124,8 @@ bool L4SysCampaign::run() {
|
||||
campaignmanager.addParam(d);
|
||||
++count;
|
||||
}
|
||||
for (int i = 0; i < 20000; ++i) {
|
||||
#endif
|
||||
for (int i = 0; i < 5000; ++i) {
|
||||
L4SysExperimentData *d = new L4SysExperimentData;
|
||||
d->msg.set_exp_type(d->msg.RATFLIP);
|
||||
// modify for a random instruction
|
||||
@ -144,13 +150,15 @@ bool L4SysCampaign::run() {
|
||||
while ((res = static_cast<L4SysExperimentData *>(campaignmanager.getDone()))) {
|
||||
rescount++;
|
||||
|
||||
results << output_experiment(res->msg.exp_type()) << "," << hex << res->msg.injection_ip() << dec << ",";
|
||||
results << l4sysExperimentConversion.output(res->msg.exp_type())
|
||||
<< "," << hex << res->msg.injection_ip() << dec << ",";
|
||||
if (res->msg.has_register_offset())
|
||||
results << output_register(res->msg.register_offset());
|
||||
results << l4sysRegisterConversion.output(res->msg.register_offset());
|
||||
else
|
||||
results << "None";
|
||||
results << "," << res->msg.instr_offset() << "," << res->msg.bit_offset()
|
||||
<< "," << output_result(res->msg.resulttype()) << ","
|
||||
<< ","
|
||||
<< l4sysResultConversion.output(res->msg.resulttype()) << ","
|
||||
<< res->msg.resultdata();
|
||||
if (res->msg.has_output())
|
||||
results << "," << res->msg.output();
|
||||
|
||||
@ -14,10 +14,6 @@ public:
|
||||
class L4SysCampaign : public fail::Campaign {
|
||||
public:
|
||||
virtual bool run();
|
||||
private:
|
||||
std::string output_result(L4SysProtoMsg_ResultType res);
|
||||
std::string output_experiment(L4SysProtoMsg_ExperimentType res);
|
||||
std::string output_register(L4SysProtoMsg_RegisterType res);
|
||||
};
|
||||
|
||||
#endif // __L4SYS_CAMPAIGN_HPP__
|
||||
|
||||
16
src/experiments/l4-sys/conversion.cc
Normal file
16
src/experiments/l4-sys/conversion.cc
Normal file
@ -0,0 +1,16 @@
|
||||
#include "conversion.hpp"
|
||||
|
||||
char const *l4sys_output_result_strings[] = { "Unknown", "No effect", "Incomplete execution", "Crash", "Silent data corruption", "Error" };
|
||||
char const *l4sys_output_experiment_strings[] = { "Unknown", "GPR Flip", "RAT Flip", "IDC Flip", "ALU Instr Flip" };
|
||||
char const *l4sys_output_register_strings[] = { "Unknown", "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" };
|
||||
|
||||
L4SysConversion l4sysResultConversion(
|
||||
l4sys_output_result_strings,
|
||||
sizeof(l4sys_output_result_strings));
|
||||
L4SysConversion l4sysExperimentConversion(
|
||||
l4sys_output_experiment_strings,
|
||||
sizeof(l4sys_output_experiment_strings));
|
||||
L4SysConversion l4sysRegisterConversion(
|
||||
l4sys_output_register_strings,
|
||||
sizeof(l4sys_output_register_strings));
|
||||
|
||||
25
src/experiments/l4-sys/conversion.hpp
Normal file
25
src/experiments/l4-sys/conversion.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef __L4SYS_CONVERSION_HPP__
|
||||
#define __L4SYS_CONVERSION_HPP__
|
||||
|
||||
#include "l4sys.pb.h"
|
||||
|
||||
class L4SysConversion {
|
||||
public:
|
||||
L4SysConversion(char const **strings, size_t array_size)
|
||||
: m_Strings(strings)
|
||||
{
|
||||
m_ElementCount = array_size / sizeof(char*);
|
||||
}
|
||||
char const * output(unsigned int res) {
|
||||
if (res == 0 || res >= m_ElementCount) {
|
||||
return m_Strings[0];
|
||||
} else {
|
||||
return m_Strings[res];
|
||||
}
|
||||
}
|
||||
private:
|
||||
char const **m_Strings;
|
||||
size_t m_ElementCount;
|
||||
};
|
||||
|
||||
#endif // __L4SYS_CONVERSION_HPP__
|
||||
@ -12,6 +12,7 @@
|
||||
#include "InstructionFilter.hpp"
|
||||
#include "aluinstr.hpp"
|
||||
#include "campaign.hpp"
|
||||
#include "conversion.hpp"
|
||||
|
||||
#include "sal/SALConfig.hpp"
|
||||
#include "sal/SALInst.hpp"
|
||||
@ -35,6 +36,7 @@ using namespace fail;
|
||||
|
||||
string output;
|
||||
string golden_run;
|
||||
extern L4SysConversion l4sysRegisterConversion;
|
||||
|
||||
string L4SysExperiment::sanitised(const string &in_str) {
|
||||
string result;
|
||||
@ -191,6 +193,17 @@ void L4SysExperiment::terminate(int reason) {
|
||||
simulator.terminate(reason);
|
||||
}
|
||||
|
||||
void L4SysExperiment::terminateWithError(string details, int reason) {
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
param->msg.set_details(details);
|
||||
|
||||
m_jc.sendResult(*param);
|
||||
terminate(reason);
|
||||
}
|
||||
|
||||
bool L4SysExperiment::run() {
|
||||
BPSingleListener bp(0, L4SYS_ADDRESS_SPACE);
|
||||
srand(time(NULL));
|
||||
@ -203,9 +216,11 @@ bool L4SysExperiment::run() {
|
||||
simulator.addListenerAndResume(&bp);
|
||||
|
||||
log << "test function entry reached, saving state" << endl;
|
||||
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
|
||||
log << "EIP: expected " << hex << bp.getTriggerInstructionPointer()
|
||||
<< " and actually got "
|
||||
<< simulator.getCPU(0).getInstructionPointer()
|
||||
<< endl;
|
||||
log << "check the source code if the two instruction pointers are not equal" << endl;
|
||||
simulator.save(L4SYS_STATE_FOLDER);
|
||||
#elif PREPARATION_STEP == 2
|
||||
// STEP 2: determine instructions executed
|
||||
@ -375,28 +390,16 @@ bool L4SysExperiment::run() {
|
||||
ss << "SANITY CHECK FAILED: " << injection_ip << " != "
|
||||
<< curr_instr.trigger_addr;
|
||||
log << ss.str() << endl;
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(injection_ip);
|
||||
param->msg.set_details(ss.str());
|
||||
|
||||
m_jc.sendResult(*param);
|
||||
terminate(20);
|
||||
terminateWithError(ss.str(), 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
// inject
|
||||
if (exp_type == param->msg.GPRFLIP) {
|
||||
if (!param->msg.has_register_offset()) {
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
|
||||
stringstream ss;
|
||||
ss << "Sent package did not contain the injection location (register offset)";
|
||||
param->msg.set_details(ss.str());
|
||||
m_jc.sendResult(*param);
|
||||
terminate(30);
|
||||
terminateWithError(
|
||||
"Sent package did not contain the injection location (register offset)",
|
||||
30);
|
||||
}
|
||||
int reg_offset = param->msg.register_offset();
|
||||
ConcreteCPU& cpu = simulator.getCPU(0);
|
||||
@ -448,11 +451,6 @@ bool L4SysExperiment::run() {
|
||||
// do the logging
|
||||
logInjection();
|
||||
} else if (exp_type == param->msg.RATFLIP) {
|
||||
/*
|
||||
TODO: provide information on the affected register
|
||||
in param->msg.register and on its destination in
|
||||
param->msg.details
|
||||
*/
|
||||
ud_type_t which = UD_NONE;
|
||||
unsigned rnd = 0;
|
||||
Udis86 udis(injection_ip);
|
||||
@ -460,16 +458,8 @@ bool L4SysExperiment::run() {
|
||||
bxInstruction_c *currInstr = simulator.getCurrentInstruction();
|
||||
udis.setInputBuffer(calculateInstructionAddress(), currInstr->ilen());
|
||||
if (!udis.fetchNextInstruction()) {
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
|
||||
stringstream ss;
|
||||
ss << "Could not decode instruction using UDIS86";
|
||||
param->msg.set_details(ss.str());
|
||||
m_jc.sendResult(*param);
|
||||
terminate(32);
|
||||
terminateWithError(
|
||||
"Could not decode instruction using UDIS86", 32);
|
||||
}
|
||||
ud_t _ud = udis.getCurrentState();
|
||||
|
||||
@ -522,16 +512,11 @@ bool L4SysExperiment::run() {
|
||||
simulator.getCPU(0).getInstructionPointer() != L4SYS_FUNC_EXIT);
|
||||
|
||||
if (simulator.getCPU(0).getInstructionPointer() == L4SYS_FUNC_EXIT) {
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
|
||||
stringstream ss;
|
||||
ss << "Reached the end of the experiment without finding an appropriate instruction";
|
||||
param->msg.set_details(ss.str());
|
||||
m_jc.sendResult(*param);
|
||||
terminate(33);
|
||||
ss << "Reached the end of the experiment ";
|
||||
ss << "without finding an appropriate instruction";
|
||||
|
||||
terminateWithError(ss.str(), 33);
|
||||
}
|
||||
|
||||
// store the real injection point
|
||||
@ -542,7 +527,8 @@ bool L4SysExperiment::run() {
|
||||
|
||||
// some declarations
|
||||
GPRegisterId bochs_reg = Udis86::udisGPRToFailBochsGPR(which);
|
||||
int exchg_reg = -1;
|
||||
param->msg.set_register_offset(
|
||||
static_cast<L4SysProtoMsg_RegisterType>(bochs_reg + 1));
|
||||
ConcreteCPU &cpu = simulator.getCPU(0);
|
||||
Register *bochsRegister = cpu.getRegister(bochs_reg);
|
||||
Register *exchangeRegister = NULL;
|
||||
@ -551,10 +537,11 @@ bool L4SysExperiment::run() {
|
||||
// (ten percent chance)
|
||||
if (rand() % 10 == 0) {
|
||||
// assure exchange of registers
|
||||
exchg_reg = rand() % 7;
|
||||
unsigned int exchg_reg = rand() % 7;
|
||||
if (exchg_reg == bochs_reg)
|
||||
exchg_reg++;
|
||||
exchangeRegister = cpu.getRegister(exchg_reg);
|
||||
param->msg.set_details(l4sysRegisterConversion.output(exchg_reg + 1));
|
||||
}
|
||||
|
||||
// prepare the fault
|
||||
@ -562,7 +549,7 @@ bool L4SysExperiment::run() {
|
||||
if (rnd > 0) {
|
||||
//input register - do the fault injection here
|
||||
regdata_t newdata = 0;
|
||||
if (exchangeRegister >= 0) {
|
||||
if (exchangeRegister != NULL) {
|
||||
// the data is taken from a process register chosen before
|
||||
newdata = cpu.getRegisterContent(exchangeRegister);
|
||||
} else {
|
||||
@ -578,7 +565,7 @@ bool L4SysExperiment::run() {
|
||||
// restore the register if we are still in the thread
|
||||
if (rnd == 0) {
|
||||
// output register - do the fault injection here
|
||||
if (exchangeRegister >= 0) {
|
||||
if (exchangeRegister != NULL) {
|
||||
// write the result into the wrong local register
|
||||
regdata_t newdata = cpu.getRegisterContent(bochsRegister);
|
||||
cpu.setRegisterContent(exchangeRegister, newdata);
|
||||
@ -604,16 +591,11 @@ bool L4SysExperiment::run() {
|
||||
}
|
||||
|
||||
if (simulator.getCPU(0).getInstructionPointer() == L4SYS_FUNC_EXIT) {
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
|
||||
stringstream ss;
|
||||
ss << "Reached the end of the experiment without finding an appropriate instruction";
|
||||
param->msg.set_details(ss.str());
|
||||
m_jc.sendResult(*param);
|
||||
terminate(33);
|
||||
ss << "Reached the end of the experiment ";
|
||||
ss << "without finding an appropriate instruction";
|
||||
|
||||
terminateWithError(ss.str(), 34);
|
||||
}
|
||||
|
||||
// store the real injection point
|
||||
@ -625,16 +607,9 @@ bool L4SysExperiment::run() {
|
||||
aluInstrObject.randomEquivalent(newInstr, details);
|
||||
if (memcmp(&newInstr, currInstr, sizeof(bxInstruction_c)) == 0) {
|
||||
// something went wrong - exit experiment
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
|
||||
ostringstream oss;
|
||||
oss << "Did not hit an ALU instruction - correct the source code please!";
|
||||
param->msg.set_details(oss.str());
|
||||
m_jc.sendResult(*param);
|
||||
terminate(40);
|
||||
terminateWithError(
|
||||
"Did not hit an ALU instruction - correct the source code please!",
|
||||
40);
|
||||
}
|
||||
// record information on the new instruction
|
||||
param->msg.set_details(details);
|
||||
@ -688,15 +663,9 @@ bool L4SysExperiment::run() {
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
} else {
|
||||
log << "Result WTF?" << endl;
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
|
||||
stringstream ss;
|
||||
ss << "eventid " << ev << " EIP "
|
||||
<< simulator.getCPU(0).getInstructionPointer();
|
||||
param->msg.set_details(ss.str());
|
||||
ss << "eventid " << ev;
|
||||
terminateWithError(ss.str(), 50);
|
||||
}
|
||||
|
||||
m_jc.sendResult(*param);
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
195c195
|
||||
< BPSingleListener bp(0, L4SYS_ADDRESS_SPACE);
|
||||
---
|
||||
> BPSingleListener bp(0, ANY_ADDR);
|
||||
202,209c202,210
|
||||
< bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
|
||||
< simulator.addListenerAndResume(&bp);
|
||||
<
|
||||
< log << "test function entry reached, saving state" << endl;
|
||||
< log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
|
||||
< << simulator.getRegisterManager().getInstructionPointer()
|
||||
< << endl;
|
||||
< simulator.save(L4SYS_STATE_FOLDER);
|
||||
---
|
||||
> for (int i = 0; i < 500; i++) {
|
||||
> bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
|
||||
> simulator.addListenerAndResume(&bp);
|
||||
> log << "test function entry reached" << endl;
|
||||
> log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
|
||||
> << simulator.getRegisterManager().getInstructionPointer()
|
||||
> << endl;
|
||||
> simulator.removeListener(&bp);
|
||||
> }
|
||||
@ -102,6 +102,10 @@ private:
|
||||
* Calculate the timeout of the current workload in milliseconds.
|
||||
*/
|
||||
unsigned calculateTimeout(unsigned instr_left);
|
||||
/**
|
||||
* Send back the experiment parameter set with a description of the error.
|
||||
*/
|
||||
void terminateWithError(std::string details, int reason);
|
||||
};
|
||||
|
||||
#endif // __L4SYS_EXPERIMENT_HPP__
|
||||
|
||||
@ -5,11 +5,11 @@
|
||||
#define MAX_INSTR_BYTES 15
|
||||
|
||||
// the bounds of the program (space, instructions and time)
|
||||
#define L4SYS_ADDRESS_SPACE 0x203d000
|
||||
#define L4SYS_ADDRESS_SPACE 0x1fe0000
|
||||
#define L4SYS_FUNC_ENTRY 0x10025ca
|
||||
#define L4SYS_FUNC_EXIT 0x1002810
|
||||
// kernel: 3597806, userland: 79484908
|
||||
#define L4SYS_NUMINSTR 83082714
|
||||
// kernel: 2377547, userland: 79405472
|
||||
#define L4SYS_NUMINSTR 81783019
|
||||
#define L4SYS_BOCHS_IPS 5000000
|
||||
|
||||
// several file names used
|
||||
|
||||
@ -12,17 +12,17 @@ message L4SysProtoMsg {
|
||||
required int32 bit_offset = 3;
|
||||
|
||||
// registers
|
||||
enum RegisterType {
|
||||
EAX = 1;
|
||||
ECX = 2;
|
||||
EDX = 3;
|
||||
EBX = 4;
|
||||
ESP = 5;
|
||||
EBP = 6;
|
||||
ESI = 7;
|
||||
EDI = 8;
|
||||
}
|
||||
optional RegisterType register_offset = 4;
|
||||
enum RegisterType {
|
||||
EAX = 1;
|
||||
ECX = 2;
|
||||
EDX = 3;
|
||||
EBX = 4;
|
||||
ESP = 5;
|
||||
EBP = 6;
|
||||
ESI = 7;
|
||||
EDI = 8;
|
||||
}
|
||||
optional RegisterType register_offset = 4;
|
||||
|
||||
// results
|
||||
// make these optional to reduce overhead for server->client communication
|
||||
|
||||
Binary file not shown.
@ -81,8 +81,8 @@ you may set \verb+L4SYS_ADDRESS_SPACE+ to \verb+ANY_ADDR+. Keep in mind that in
|
||||
that case, your instruction addresses must be unique among all those
|
||||
executed in the system, which in general is not the case.
|
||||
|
||||
Basically, there are two ways to find out the identifier of a certain
|
||||
address space in Fail*: You can look up the value in
|
||||
To find out the value of the address space identifier, you will have to
|
||||
look up the value in
|
||||
the emulator using a debugger. In the case of Bochs, you may want to
|
||||
study
|
||||
\href{http://bochs.sourceforge.net/doc/docbook/user/internal-debugger.html}{this page},
|
||||
@ -90,38 +90,8 @@ and, according to its instructions,
|
||||
dump the content of the CR3 control register at the
|
||||
beginning of your program.
|
||||
|
||||
You can also utilise the Fail* framework, which is easier and more reliable,
|
||||
but as there is no real reason to include this ``feature'' in the framework,
|
||||
in order to do so, you need to patch it. Namely,
|
||||
\texttt{src/core/sal/Listener.cc} and
|
||||
\texttt{src/experiments/l4-sys/experiment.cc}
|
||||
need to be modified using the two patch files supplied alongside with this
|
||||
manual in the current directory.
|
||||
You should check the patch files for their release date and content:
|
||||
In case the framework's
|
||||
event handling structure has changed, the line numbers in
|
||||
\texttt{Listener.cc} are incorrect,
|
||||
and you need to apply the patch manually.
|
||||
|
||||
As soon as you have applied the patch, set \verb+PREPARATION_STEP+
|
||||
to \texttt{1} in \texttt{experimentInfo.hpp} and recompile the framework.
|
||||
Now start the experiment client (\texttt{fail-client}) in your
|
||||
emulator directory, and
|
||||
it will show you which address space is active whenever a
|
||||
breakpoint triggers.
|
||||
Ideally, you still have a graphical interface enabled to
|
||||
monitor your system's progress and check if the breakpoints
|
||||
are triggered at the right points in time.
|
||||
|
||||
When your program has reached the function entry point,
|
||||
note the address space and exit the program simply by pressing Ctrl+C.
|
||||
|
||||
\subsection{Step 1: Save the initial state of the machine}
|
||||
|
||||
If you have modified the Fail* framework in Step 0,
|
||||
you should now restore the original framework
|
||||
data using \texttt{svn revert}.
|
||||
|
||||
Make sure \verb+PREPARATION_STEP+ is still set to \texttt{1}, and
|
||||
you have set \verb+L4SYS_ADDRESS_SPACE+ accordingly.
|
||||
Now recompile and execute the framework code again, this time with the graphical
|
||||
@ -297,10 +267,7 @@ the campaign server, from left to right.
|
||||
|
||||
\section{Known bugs}
|
||||
|
||||
At the moment, RATFlip does not provide enough information
|
||||
to reconstruct the injected fault
|
||||
(see also the \texttt{TODO} in \texttt{experiment.cc}).
|
||||
Also, if you need support for more than one processor,
|
||||
If you need support for more than one processor,
|
||||
you will have to extend the code accordingly:
|
||||
at the moment, when in doubt, it uses the first CPU.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user