Initial example experiment:

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1399 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
hoffmann
2012-07-02 10:40:04 +00:00
parent 0ff2fb4dad
commit 9e41c1a39c
5 changed files with 248 additions and 0 deletions

View File

@ -0,0 +1,31 @@
set(EXPERIMENT_NAME vezs-example)
set(EXPERIMENT_TYPE VEZSExperiment)
configure_file(../instantiate-experiment.ah.in
${CMAKE_CURRENT_BINARY_DIR}/instantiate-${EXPERIMENT_NAME}.ah @ONLY
)
## Setup desired protobuf descriptions HERE ##
set(MY_PROTOS
# vezs-example.proto
)
set(MY_CAMPAIGN_SRCS
experiment.hpp
experiment.cc
#campaign.hpp
#campaign.cc
)
#### PROTOBUFS ####
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
#PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
## Build library
add_library(${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SRCS})
## This is the example's campaign server distributing experiment parameters
#add_executable(${EXPERIMENT_NAME}-server main.cc)
#target_link_libraries(${EXPERIMENT_NAME}-server ${EXPERIMENT_NAME} fail ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY})

View File

@ -0,0 +1,138 @@
#include <iostream>
#include <fstream>
// getpid
#include <sys/types.h>
#include <unistd.h>
#include "util/Logger.hpp"
#include "experiment.hpp"
#include "experimentInfo.hpp"
#include "sal/SALConfig.hpp"
#include "sal/SALInst.hpp"
#include "sal/Memory.hpp"
#include "sal/bochs/BochsRegister.hpp"
#include "sal/bochs/BochsEvents.hpp"
#include "sal/Event.hpp"
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
bool ChecksumOOStuBSExperiment::run()
{
Logger log("VEZS-Example", false);
BPSingleEvent bp;
log << "startup" << endl;
bp.setWatchInstructionPointer(ANY_ADDR);
bp.setCounter(OOSTUBS_NUMINSTR);
//simulator.addEvent(&bp);
// BPSingleEvent ev_count(ANY_ADDR);
// simulator.addEvent(&ev_count);
for (int i = 0; i < 400; ++i) { // more than 400 will be very slow (500 is max)
// XXX debug
int instr_offset = 1000;
// reaching finish() could happen before OR after FI
BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
simulator.addEvent(&func_finish);
bool finish_reached = false;
bp.setWatchInstructionPointer(ANY_ADDR);
bp.setCounter(instr_offset);
simulator.addEvent(&bp);
// finish() before FI?
if (simulator.waitAny() == &func_finish) {
finish_reached = true;
log << "experiment reached finish() before FI" << endl;
// wait for bp
simulator.waitAny();
}
// --- fault injection ---
//byte_t newdata = data ^ (1 << bit_offset);
//mm.setByte(mem_addr, newdata);
// note at what IP we did it
int32_t injection_ip = simulator.getRegisterManager().getInstructionPointer();
log << "fault injected @ ip " << injection_ip << endl;
// --- aftermath ---
// possible outcomes:
// - trap, "crash"
// - jump outside text segment
// - (XXX unaligned jump inside text segment)
// - (XXX weird instructions?)
// - (XXX results displayed?)
// - reaches THE END
// - error detected, stop
// additional info:
// - #loop iterations before/after FI
// - (XXX "sane" display?)
// catch traps as "extraordinary" ending
TrapEvent ev_trap(ANY_TRAP);
simulator.addEvent(&ev_trap);
// jump outside text segment
BPRangeEvent ev_below_text(ANY_ADDR, OOSTUBS_TEXT_START - 1);
BPRangeEvent ev_beyond_text(OOSTUBS_TEXT_END + 1, ANY_ADDR);
simulator.addEvent(&ev_below_text);
simulator.addEvent(&ev_beyond_text);
// timeout (e.g., stuck in a HLT instruction)
// 10000us = 500000 instructions
TimerEvent ev_timeout(1000000); // 50,000,000 instructions !!
simulator.addEvent(&ev_timeout);
// remaining instructions until "normal" ending
BPSingleEvent ev_end(ANY_ADDR);
ev_end.setCounter(OOSTUBS_NUMINSTR + OOSTUBS_RECOVERYINSTR - instr_offset);
simulator.addEvent(&ev_end);
// Start simulator and wait for any result
BaseEvent* ev = simulator.waitAny();
// Do we reach finish() while waiting for ev_trap/ev_done?
if (ev == &func_finish) {
finish_reached = true;
log << "experiment reached finish()" << endl;
// wait for ev_trap/ev_done
ev = simulator.waitAny();
}
// record latest IP regardless of result
//simulator.getRegisterManager().getInstructionPointer();
if (ev == &ev_end) {
log << dec << "Result FINISHED" << endl;
} else if (ev == &ev_timeout) {
log << "Result TIMEOUT" << endl;
} else if (ev == &ev_below_text || ev == &ev_beyond_text) {
log << "Result OUTSIDE" << endl;
} else if (ev == &ev_trap) {
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
} else {
log << "Result WTF?" << endl;
}
// explicitly remove all events before we leave their scope
// FIXME event destructors should remove them from the queues
simulator.clearEvents();
}
// Explicitly terminate, or the simulator will continue to run.
simulator.terminate();
}

View File

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

View File

@ -0,0 +1,50 @@
#ifndef __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
// FIXME autogenerate this
#if 1 // with ECC
// the task function's entry address:
// nm -C ecc.elf|fgrep main
#define OOSTUBS_FUNC_ENTRY 0x00101eaa
// empty function that is called explicitly when the experiment finished
// nm -C ecc.elf|fgrep "finished()"
#define OOSTUBS_FUNC_FINISH 0x00106da4
// function executing HLT with no chance for further progress (after panic())
// nm -C ecc.elf|fgrep cpu_halt
#define OOSTUBS_FUNC_CPU_HALT 0x001009f7
// nm -C ecc.elf | fgrep "_TEXT_"
#define OOSTUBS_TEXT_START 0x00100000
#define OOSTUBS_TEXT_END 0x00107cbf
// number of instructions the target executes under non-error conditions from ENTRY to DONE:
// (result of experiment's step #2)
#define OOSTUBS_NUMINSTR 0x4B16E6
// number of instructions that are executed additionally for error corrections
// (this is a rough guess ... TODO)
#define OOSTUBS_RECOVERYINSTR 0x2000
// the variable that's increased if ECC corrects an error:
// nm -C ecc.elf|fgrep errors_corrected
#define OOSTUBS_ERROR_CORRECTED 0x0010baf0
//
// nm -C ecc.elf|fgrep results
#define OOSTUBS_RESULTS_ADDR 0x0010ae6c
#define OOSTUBS_RESULTS_BYTES 12
#define OOSTUBS_RESULT0 0xab3566a9
#define OOSTUBS_RESULT1 0x44889112
#define OOSTUBS_RESULT2 0x10420844
#else // without ECC
#define COOL_ECC_FUNC_ENTRY 0x00200a90
#define COOL_ECC_CALCDONE 0x00200ab7
#define COOL_ECC_NUMINSTR 97
#define COOL_ECC_OBJUNDERTEST 0x0021263c
#define COOL_ECC_OBJUNDERTEST_SIZE 10
#define COOL_ECC_ERROR_CORRECTED 0x002127b0 // dummy
#endif
#endif // __EXPERIMENT_INFO_HPP__

View File

@ -0,0 +1,15 @@
#include <iostream>
#include <cstdlib>
#include "cpn/CampaignManager.hpp"
#include "campaign.hpp"
int main(int argc, char **argv)
{
ChecksumOOStuBSCampaign c;
if (fail::campaignmanager.runCampaign(&c)) {
return 0;
} else {
return 1;
}
}