- 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
|
UDIS86.cc
|
||||||
InstructionFilter.hpp
|
InstructionFilter.hpp
|
||||||
InstructionFilter.cc
|
InstructionFilter.cc
|
||||||
|
conversion.hpp
|
||||||
|
conversion.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
#### PROTOBUFS ####
|
#### 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 "campaign.hpp"
|
||||||
#include "experimentInfo.hpp"
|
#include "experimentInfo.hpp"
|
||||||
|
#include "conversion.hpp"
|
||||||
#include "cpn/CampaignManager.hpp"
|
#include "cpn/CampaignManager.hpp"
|
||||||
#include "util/Logger.hpp"
|
#include "util/Logger.hpp"
|
||||||
#include "sal/SALConfig.hpp"
|
#include "sal/SALConfig.hpp"
|
||||||
@ -11,10 +12,8 @@ using namespace std;
|
|||||||
using namespace fail;
|
using namespace fail;
|
||||||
|
|
||||||
char const * const results_csv = "l4sys.csv";
|
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];
|
#define OUTPUT_CASE(OUTPUT) case L4SysProtoMsg::OUTPUT: return l4sys_output_result_strings[L4SysProtoMsg::OUTPUT];
|
||||||
std::string L4SysCampaign::output_result(L4SysProtoMsg_ResultType res) {
|
std::string L4SysCampaign::output_result(L4SysProtoMsg_ResultType res) {
|
||||||
switch (res) {
|
switch (res) {
|
||||||
@ -56,6 +55,11 @@ std::string L4SysCampaign::output_register(L4SysProtoMsg_RegisterType res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef OUTPUT_CASE
|
#undef OUTPUT_CASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern L4SysConversion l4sysResultConversion;
|
||||||
|
extern L4SysConversion l4sysExperimentConversion;
|
||||||
|
extern L4SysConversion l4sysRegisterConversion;
|
||||||
|
|
||||||
bool L4SysCampaign::run() {
|
bool L4SysCampaign::run() {
|
||||||
Logger log("L4SysCampaign");
|
Logger log("L4SysCampaign");
|
||||||
@ -77,6 +81,7 @@ bool L4SysCampaign::run() {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
|
#if 0
|
||||||
for (int i = 0; i < 20000; ++i) {
|
for (int i = 0; i < 20000; ++i) {
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
L4SysExperimentData *d = new L4SysExperimentData;
|
||||||
d->msg.set_exp_type(d->msg.GPRFLIP);
|
d->msg.set_exp_type(d->msg.GPRFLIP);
|
||||||
@ -119,7 +124,8 @@ bool L4SysCampaign::run() {
|
|||||||
campaignmanager.addParam(d);
|
campaignmanager.addParam(d);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 20000; ++i) {
|
#endif
|
||||||
|
for (int i = 0; i < 5000; ++i) {
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
L4SysExperimentData *d = new L4SysExperimentData;
|
||||||
d->msg.set_exp_type(d->msg.RATFLIP);
|
d->msg.set_exp_type(d->msg.RATFLIP);
|
||||||
// modify for a random instruction
|
// modify for a random instruction
|
||||||
@ -144,13 +150,15 @@ bool L4SysCampaign::run() {
|
|||||||
while ((res = static_cast<L4SysExperimentData *>(campaignmanager.getDone()))) {
|
while ((res = static_cast<L4SysExperimentData *>(campaignmanager.getDone()))) {
|
||||||
rescount++;
|
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())
|
if (res->msg.has_register_offset())
|
||||||
results << output_register(res->msg.register_offset());
|
results << l4sysRegisterConversion.output(res->msg.register_offset());
|
||||||
else
|
else
|
||||||
results << "None";
|
results << "None";
|
||||||
results << "," << res->msg.instr_offset() << "," << res->msg.bit_offset()
|
results << "," << res->msg.instr_offset() << "," << res->msg.bit_offset()
|
||||||
<< "," << output_result(res->msg.resulttype()) << ","
|
<< ","
|
||||||
|
<< l4sysResultConversion.output(res->msg.resulttype()) << ","
|
||||||
<< res->msg.resultdata();
|
<< res->msg.resultdata();
|
||||||
if (res->msg.has_output())
|
if (res->msg.has_output())
|
||||||
results << "," << res->msg.output();
|
results << "," << res->msg.output();
|
||||||
|
|||||||
@ -14,10 +14,6 @@ public:
|
|||||||
class L4SysCampaign : public fail::Campaign {
|
class L4SysCampaign : public fail::Campaign {
|
||||||
public:
|
public:
|
||||||
virtual bool run();
|
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__
|
#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 "InstructionFilter.hpp"
|
||||||
#include "aluinstr.hpp"
|
#include "aluinstr.hpp"
|
||||||
#include "campaign.hpp"
|
#include "campaign.hpp"
|
||||||
|
#include "conversion.hpp"
|
||||||
|
|
||||||
#include "sal/SALConfig.hpp"
|
#include "sal/SALConfig.hpp"
|
||||||
#include "sal/SALInst.hpp"
|
#include "sal/SALInst.hpp"
|
||||||
@ -35,6 +36,7 @@ using namespace fail;
|
|||||||
|
|
||||||
string output;
|
string output;
|
||||||
string golden_run;
|
string golden_run;
|
||||||
|
extern L4SysConversion l4sysRegisterConversion;
|
||||||
|
|
||||||
string L4SysExperiment::sanitised(const string &in_str) {
|
string L4SysExperiment::sanitised(const string &in_str) {
|
||||||
string result;
|
string result;
|
||||||
@ -191,6 +193,17 @@ void L4SysExperiment::terminate(int reason) {
|
|||||||
simulator.terminate(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() {
|
bool L4SysExperiment::run() {
|
||||||
BPSingleListener bp(0, L4SYS_ADDRESS_SPACE);
|
BPSingleListener bp(0, L4SYS_ADDRESS_SPACE);
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
@ -203,9 +216,11 @@ bool L4SysExperiment::run() {
|
|||||||
simulator.addListenerAndResume(&bp);
|
simulator.addListenerAndResume(&bp);
|
||||||
|
|
||||||
log << "test function entry reached, saving state" << endl;
|
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()
|
<< simulator.getCPU(0).getInstructionPointer()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
log << "check the source code if the two instruction pointers are not equal" << endl;
|
||||||
simulator.save(L4SYS_STATE_FOLDER);
|
simulator.save(L4SYS_STATE_FOLDER);
|
||||||
#elif PREPARATION_STEP == 2
|
#elif PREPARATION_STEP == 2
|
||||||
// STEP 2: determine instructions executed
|
// STEP 2: determine instructions executed
|
||||||
@ -375,28 +390,16 @@ bool L4SysExperiment::run() {
|
|||||||
ss << "SANITY CHECK FAILED: " << injection_ip << " != "
|
ss << "SANITY CHECK FAILED: " << injection_ip << " != "
|
||||||
<< curr_instr.trigger_addr;
|
<< curr_instr.trigger_addr;
|
||||||
log << ss.str() << endl;
|
log << ss.str() << endl;
|
||||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
terminateWithError(ss.str(), 20);
|
||||||
param->msg.set_resultdata(injection_ip);
|
|
||||||
param->msg.set_details(ss.str());
|
|
||||||
|
|
||||||
m_jc.sendResult(*param);
|
|
||||||
terminate(20);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// inject
|
// inject
|
||||||
if (exp_type == param->msg.GPRFLIP) {
|
if (exp_type == param->msg.GPRFLIP) {
|
||||||
if (!param->msg.has_register_offset()) {
|
if (!param->msg.has_register_offset()) {
|
||||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
terminateWithError(
|
||||||
param->msg.set_resultdata(
|
"Sent package did not contain the injection location (register offset)",
|
||||||
simulator.getCPU(0).getInstructionPointer());
|
30);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
int reg_offset = param->msg.register_offset();
|
int reg_offset = param->msg.register_offset();
|
||||||
ConcreteCPU& cpu = simulator.getCPU(0);
|
ConcreteCPU& cpu = simulator.getCPU(0);
|
||||||
@ -448,11 +451,6 @@ bool L4SysExperiment::run() {
|
|||||||
// do the logging
|
// do the logging
|
||||||
logInjection();
|
logInjection();
|
||||||
} else if (exp_type == param->msg.RATFLIP) {
|
} 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;
|
ud_type_t which = UD_NONE;
|
||||||
unsigned rnd = 0;
|
unsigned rnd = 0;
|
||||||
Udis86 udis(injection_ip);
|
Udis86 udis(injection_ip);
|
||||||
@ -460,16 +458,8 @@ bool L4SysExperiment::run() {
|
|||||||
bxInstruction_c *currInstr = simulator.getCurrentInstruction();
|
bxInstruction_c *currInstr = simulator.getCurrentInstruction();
|
||||||
udis.setInputBuffer(calculateInstructionAddress(), currInstr->ilen());
|
udis.setInputBuffer(calculateInstructionAddress(), currInstr->ilen());
|
||||||
if (!udis.fetchNextInstruction()) {
|
if (!udis.fetchNextInstruction()) {
|
||||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
terminateWithError(
|
||||||
param->msg.set_resultdata(
|
"Could not decode instruction using UDIS86", 32);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
ud_t _ud = udis.getCurrentState();
|
ud_t _ud = udis.getCurrentState();
|
||||||
|
|
||||||
@ -522,16 +512,11 @@ bool L4SysExperiment::run() {
|
|||||||
simulator.getCPU(0).getInstructionPointer() != L4SYS_FUNC_EXIT);
|
simulator.getCPU(0).getInstructionPointer() != L4SYS_FUNC_EXIT);
|
||||||
|
|
||||||
if (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;
|
stringstream ss;
|
||||||
ss << "Reached the end of the experiment without finding an appropriate instruction";
|
ss << "Reached the end of the experiment ";
|
||||||
param->msg.set_details(ss.str());
|
ss << "without finding an appropriate instruction";
|
||||||
m_jc.sendResult(*param);
|
|
||||||
terminate(33);
|
terminateWithError(ss.str(), 33);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the real injection point
|
// store the real injection point
|
||||||
@ -542,7 +527,8 @@ bool L4SysExperiment::run() {
|
|||||||
|
|
||||||
// some declarations
|
// some declarations
|
||||||
GPRegisterId bochs_reg = Udis86::udisGPRToFailBochsGPR(which);
|
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);
|
ConcreteCPU &cpu = simulator.getCPU(0);
|
||||||
Register *bochsRegister = cpu.getRegister(bochs_reg);
|
Register *bochsRegister = cpu.getRegister(bochs_reg);
|
||||||
Register *exchangeRegister = NULL;
|
Register *exchangeRegister = NULL;
|
||||||
@ -551,10 +537,11 @@ bool L4SysExperiment::run() {
|
|||||||
// (ten percent chance)
|
// (ten percent chance)
|
||||||
if (rand() % 10 == 0) {
|
if (rand() % 10 == 0) {
|
||||||
// assure exchange of registers
|
// assure exchange of registers
|
||||||
exchg_reg = rand() % 7;
|
unsigned int exchg_reg = rand() % 7;
|
||||||
if (exchg_reg == bochs_reg)
|
if (exchg_reg == bochs_reg)
|
||||||
exchg_reg++;
|
exchg_reg++;
|
||||||
exchangeRegister = cpu.getRegister(exchg_reg);
|
exchangeRegister = cpu.getRegister(exchg_reg);
|
||||||
|
param->msg.set_details(l4sysRegisterConversion.output(exchg_reg + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare the fault
|
// prepare the fault
|
||||||
@ -562,7 +549,7 @@ bool L4SysExperiment::run() {
|
|||||||
if (rnd > 0) {
|
if (rnd > 0) {
|
||||||
//input register - do the fault injection here
|
//input register - do the fault injection here
|
||||||
regdata_t newdata = 0;
|
regdata_t newdata = 0;
|
||||||
if (exchangeRegister >= 0) {
|
if (exchangeRegister != NULL) {
|
||||||
// the data is taken from a process register chosen before
|
// the data is taken from a process register chosen before
|
||||||
newdata = cpu.getRegisterContent(exchangeRegister);
|
newdata = cpu.getRegisterContent(exchangeRegister);
|
||||||
} else {
|
} else {
|
||||||
@ -578,7 +565,7 @@ bool L4SysExperiment::run() {
|
|||||||
// restore the register if we are still in the thread
|
// restore the register if we are still in the thread
|
||||||
if (rnd == 0) {
|
if (rnd == 0) {
|
||||||
// output register - do the fault injection here
|
// output register - do the fault injection here
|
||||||
if (exchangeRegister >= 0) {
|
if (exchangeRegister != NULL) {
|
||||||
// write the result into the wrong local register
|
// write the result into the wrong local register
|
||||||
regdata_t newdata = cpu.getRegisterContent(bochsRegister);
|
regdata_t newdata = cpu.getRegisterContent(bochsRegister);
|
||||||
cpu.setRegisterContent(exchangeRegister, newdata);
|
cpu.setRegisterContent(exchangeRegister, newdata);
|
||||||
@ -604,16 +591,11 @@ bool L4SysExperiment::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (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;
|
stringstream ss;
|
||||||
ss << "Reached the end of the experiment without finding an appropriate instruction";
|
ss << "Reached the end of the experiment ";
|
||||||
param->msg.set_details(ss.str());
|
ss << "without finding an appropriate instruction";
|
||||||
m_jc.sendResult(*param);
|
|
||||||
terminate(33);
|
terminateWithError(ss.str(), 34);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the real injection point
|
// store the real injection point
|
||||||
@ -625,16 +607,9 @@ bool L4SysExperiment::run() {
|
|||||||
aluInstrObject.randomEquivalent(newInstr, details);
|
aluInstrObject.randomEquivalent(newInstr, details);
|
||||||
if (memcmp(&newInstr, currInstr, sizeof(bxInstruction_c)) == 0) {
|
if (memcmp(&newInstr, currInstr, sizeof(bxInstruction_c)) == 0) {
|
||||||
// something went wrong - exit experiment
|
// something went wrong - exit experiment
|
||||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
terminateWithError(
|
||||||
param->msg.set_resultdata(
|
"Did not hit an ALU instruction - correct the source code please!",
|
||||||
simulator.getCPU(0).getInstructionPointer());
|
40);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
// record information on the new instruction
|
// record information on the new instruction
|
||||||
param->msg.set_details(details);
|
param->msg.set_details(details);
|
||||||
@ -688,15 +663,9 @@ bool L4SysExperiment::run() {
|
|||||||
param->msg.set_output(sanitised(output.c_str()));
|
param->msg.set_output(sanitised(output.c_str()));
|
||||||
} else {
|
} else {
|
||||||
log << "Result WTF?" << endl;
|
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;
|
stringstream ss;
|
||||||
ss << "eventid " << ev << " EIP "
|
ss << "eventid " << ev;
|
||||||
<< simulator.getCPU(0).getInstructionPointer();
|
terminateWithError(ss.str(), 50);
|
||||||
param->msg.set_details(ss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_jc.sendResult(*param);
|
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.
|
* Calculate the timeout of the current workload in milliseconds.
|
||||||
*/
|
*/
|
||||||
unsigned calculateTimeout(unsigned instr_left);
|
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__
|
#endif // __L4SYS_EXPERIMENT_HPP__
|
||||||
|
|||||||
@ -5,11 +5,11 @@
|
|||||||
#define MAX_INSTR_BYTES 15
|
#define MAX_INSTR_BYTES 15
|
||||||
|
|
||||||
// the bounds of the program (space, instructions and time)
|
// 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_ENTRY 0x10025ca
|
||||||
#define L4SYS_FUNC_EXIT 0x1002810
|
#define L4SYS_FUNC_EXIT 0x1002810
|
||||||
// kernel: 3597806, userland: 79484908
|
// kernel: 2377547, userland: 79405472
|
||||||
#define L4SYS_NUMINSTR 83082714
|
#define L4SYS_NUMINSTR 81783019
|
||||||
#define L4SYS_BOCHS_IPS 5000000
|
#define L4SYS_BOCHS_IPS 5000000
|
||||||
|
|
||||||
// several file names used
|
// several file names used
|
||||||
|
|||||||
@ -12,17 +12,17 @@ message L4SysProtoMsg {
|
|||||||
required int32 bit_offset = 3;
|
required int32 bit_offset = 3;
|
||||||
|
|
||||||
// registers
|
// registers
|
||||||
enum RegisterType {
|
enum RegisterType {
|
||||||
EAX = 1;
|
EAX = 1;
|
||||||
ECX = 2;
|
ECX = 2;
|
||||||
EDX = 3;
|
EDX = 3;
|
||||||
EBX = 4;
|
EBX = 4;
|
||||||
ESP = 5;
|
ESP = 5;
|
||||||
EBP = 6;
|
EBP = 6;
|
||||||
ESI = 7;
|
ESI = 7;
|
||||||
EDI = 8;
|
EDI = 8;
|
||||||
}
|
}
|
||||||
optional RegisterType register_offset = 4;
|
optional RegisterType register_offset = 4;
|
||||||
|
|
||||||
// results
|
// results
|
||||||
// make these optional to reduce overhead for server->client communication
|
// 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
|
that case, your instruction addresses must be unique among all those
|
||||||
executed in the system, which in general is not the case.
|
executed in the system, which in general is not the case.
|
||||||
|
|
||||||
Basically, there are two ways to find out the identifier of a certain
|
To find out the value of the address space identifier, you will have to
|
||||||
address space in Fail*: You can look up the value in
|
look up the value in
|
||||||
the emulator using a debugger. In the case of Bochs, you may want to
|
the emulator using a debugger. In the case of Bochs, you may want to
|
||||||
study
|
study
|
||||||
\href{http://bochs.sourceforge.net/doc/docbook/user/internal-debugger.html}{this page},
|
\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
|
dump the content of the CR3 control register at the
|
||||||
beginning of your program.
|
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}
|
\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
|
Make sure \verb+PREPARATION_STEP+ is still set to \texttt{1}, and
|
||||||
you have set \verb+L4SYS_ADDRESS_SPACE+ accordingly.
|
you have set \verb+L4SYS_ADDRESS_SPACE+ accordingly.
|
||||||
Now recompile and execute the framework code again, this time with the graphical
|
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}
|
\section{Known bugs}
|
||||||
|
|
||||||
At the moment, RATFlip does not provide enough information
|
If you need support for more than one processor,
|
||||||
to reconstruct the injected fault
|
|
||||||
(see also the \texttt{TODO} in \texttt{experiment.cc}).
|
|
||||||
Also, if you need support for more than one processor,
|
|
||||||
you will have to extend the code accordingly:
|
you will have to extend the code accordingly:
|
||||||
at the moment, when in doubt, it uses the first CPU.
|
at the moment, when in doubt, it uses the first CPU.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user