From 9e41c1a39c1ef7eefc6a214a15274c943140dff0 Mon Sep 17 00:00:00 2001 From: hoffmann Date: Mon, 2 Jul 2012 10:40:04 +0000 Subject: [PATCH] Initial example experiment: git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1399 8c4709b5-6ec9-48aa-a5cd-a96041d1645a --- src/experiments/vezs-example/CMakeLists.txt | 31 ++++ src/experiments/vezs-example/experiment.cc | 138 ++++++++++++++++++ src/experiments/vezs-example/experiment.hpp | 14 ++ .../vezs-example/experimentInfo.hpp | 50 +++++++ src/experiments/vezs-example/main.cc | 15 ++ 5 files changed, 248 insertions(+) create mode 100644 src/experiments/vezs-example/CMakeLists.txt create mode 100644 src/experiments/vezs-example/experiment.cc create mode 100644 src/experiments/vezs-example/experiment.hpp create mode 100644 src/experiments/vezs-example/experimentInfo.hpp create mode 100644 src/experiments/vezs-example/main.cc diff --git a/src/experiments/vezs-example/CMakeLists.txt b/src/experiments/vezs-example/CMakeLists.txt new file mode 100644 index 00000000..5b67b3a9 --- /dev/null +++ b/src/experiments/vezs-example/CMakeLists.txt @@ -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}) diff --git a/src/experiments/vezs-example/experiment.cc b/src/experiments/vezs-example/experiment.cc new file mode 100644 index 00000000..716c0695 --- /dev/null +++ b/src/experiments/vezs-example/experiment.cc @@ -0,0 +1,138 @@ +#include +#include + +// getpid +#include +#include + +#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(); +} diff --git a/src/experiments/vezs-example/experiment.hpp b/src/experiments/vezs-example/experiment.hpp new file mode 100644 index 00000000..a0ab7a98 --- /dev/null +++ b/src/experiments/vezs-example/experiment.hpp @@ -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__ diff --git a/src/experiments/vezs-example/experimentInfo.hpp b/src/experiments/vezs-example/experimentInfo.hpp new file mode 100644 index 00000000..80a6e166 --- /dev/null +++ b/src/experiments/vezs-example/experimentInfo.hpp @@ -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__ diff --git a/src/experiments/vezs-example/main.cc b/src/experiments/vezs-example/main.cc new file mode 100644 index 00000000..16605ac5 --- /dev/null +++ b/src/experiments/vezs-example/main.cc @@ -0,0 +1,15 @@ +#include +#include + +#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; + } +}