ecos_kernel_test: merge experiment steps 0-2 into a single run

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1443 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
chb
2012-07-09 13:58:47 +00:00
parent 4aa4943ae9
commit bc922a98d3
6 changed files with 232 additions and 184 deletions

View File

@ -1,5 +1,6 @@
#include <iostream>
#include <fstream>
//#include <string>
// getpid
#include <sys/types.h>
@ -19,8 +20,6 @@
// You need to have the tracing plugin enabled for this
#include "../plugins/tracing/TracingPlugin.hpp"
#include "ecc_region.hpp"
#define LOCAL 0
using namespace std;
@ -32,6 +31,9 @@ using namespace fail;
#error This experiment needs: breakpoints, traps, save, and restore. Enable these in the configuration.
#endif
char const * const mm_filename = "memory_map.txt";
bool EcosKernelTestExperiment::run()
{
char const *statename = "ecos_kernel_test.state";
@ -40,88 +42,160 @@ bool EcosKernelTestExperiment::run()
log << "startup" << endl;
#if 0
// STEP 0: record memory map with addresses of "interesting" objects
GuestEvent g;
while (true) {
simulator.addEventAndWait(&g);
cout << g.getData() << flush;
log << "STEP 0: record memory map with addresses of 'interesting' objects" << endl;
{
// workaround for 00002808875p[BIOS ] >>PANIC<< Keyboard error:21
bp.setWatchInstructionPointer(ANY_ADDR);
simulator.addEventAndWait(&bp);
GuestEvent g;
simulator.addEvent(&g);
// 10000us = 500000 instructions
TimerEvent record_timeout(50000000); //TODO: how long to wait?
simulator.addEvent(&record_timeout);
// memory map serialization
ofstream mm(mm_filename, ios::out | ios::app);
if (!mm.is_open()) {
log << "failed to open " << mm_filename << endl;
return false;
}
string *str = new string; // buffer for guest events
unsigned number_of_guest_events = 0;
while (simulator.waitAny() != &record_timeout) {
simulator.addEvent(&g);
str->push_back(g.getData());
if (g.getData() == '\t') {
// addr complete?
//cout << "full: " << *str << "sub: " << str->substr(str->find_last_of('x') - 1) << endl;
// interpret the string obtained by the guest events as address in hex
unsigned guest_addr;
stringstream converter(str->substr(str->find_last_of('x') + 1));
converter >> hex >> guest_addr;
mm << guest_addr << '\t';
str->clear();
} else if (g.getData() == '\n') {
// len complete?
// interpret the string obtained by the guest events as length in decimal
unsigned guest_len;
stringstream converter(*str);
converter >> dec >> guest_len;
mm << guest_len << '\n';
str->clear();
number_of_guest_events++;
}
}
assert(number_of_guest_events > 0);
cout << "Record timeout reached: created memory map (" << number_of_guest_events << " entries)" << endl;
delete str;
// close serialized mm
mm.flush();
mm.close();
// clean up simulator and reboot the guest system
simulator.clearEvents();
log << "rebooting ..." << endl;
simulator.reboot();
}
#elif 0
// STEP 1: run until interesting function starts, and save state
bp.setWatchInstructionPointer(ECOS_FUNC_ENTRY);
simulator.addEventAndWait(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
//log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
simulator.save(statename);
assert(bp.getTriggerInstructionPointer() == ECOS_FUNC_ENTRY);
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
#elif 0
// STEP 2: record trace for fault-space pruning
log << "restoring state" << endl;
simulator.restore(statename);
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
log << "enabling tracing" << endl;
TracingPlugin tp;
log << "STEP 1: run until interesting function starts, and save state" << endl;
{
GuestEvent g;
// restrict memory access logging to injection target
MemoryMap mm;
for (unsigned i = 0; i < sizeof(memoryMap)/sizeof(*memoryMap); ++i) {
mm.add(memoryMap[i][0], memoryMap[i][1]);
while (true) {
simulator.addEventAndWait(&g);
if(g.getData() == 'Q') {
cout << "Guest system triggered: " << g.getData() << endl;
break;
}
}
bp.setWatchInstructionPointer(ECOS_FUNC_ENTRY);
simulator.addEventAndWait(&bp);
log << "test function entry reached, saving state" << endl;
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
//log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
simulator.save(statename);
assert(bp.getTriggerInstructionPointer() == ECOS_FUNC_ENTRY);
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
// clean up simulator and reboot the guest system
simulator.clearEvents();
log << "rebooting ..." << endl;
simulator.reboot();
}
tp.restrictMemoryAddresses(&mm);
// record trace
char const *tracefile = "trace.tc";
ofstream of(tracefile);
tp.setTraceFile(&of);
log << "STEP 2: record trace for fault-space pruning" << endl;
{
log << "restoring state" << endl;
simulator.restore(statename);
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
assert(simulator.getRegisterManager().getInstructionPointer() == ECOS_FUNC_ENTRY);
// this must be done *after* configuring the plugin:
simulator.addFlow(&tp);
log << "enabling tracing" << endl;
TracingPlugin tp;
// restrict memory access logging to injection target
MemoryMap mm;
EcosKernelTestCampaign::readMemoryMap(mm, mm_filename);
tp.restrictMemoryAddresses(&mm);
// record trace
char const *tracefile = "trace.tc";
ofstream of(tracefile);
tp.setTraceFile(&of);
// this must be done *after* configuring the plugin:
simulator.addFlow(&tp);
#if 1
// trace WEATHER_NUMITER_TRACING measurement loop iterations
// -> calibration
bp.setWatchInstructionPointer(ECOS_FUNC_FINISH);
//bp.setCounter(WEATHER_NUMITER_TRACING); // single event, only
// trace WEATHER_NUMITER_TRACING measurement loop iterations
// -> calibration
bp.setWatchInstructionPointer(ECOS_FUNC_FINISH);
//bp.setCounter(WEATHER_NUMITER_TRACING); // single event, only
#else
// FIXME this doesn't work properly: trace is one instruction too short as
// tp is removed before all events were delivered
// trace WEATHER_NUMINSTR_TRACING instructions
// -> campaign-ready traces with identical lengths
bp.setWatchInstructionPointer(ANY_ADDR);
bp.setCounter(OOSTUBS_NUMINSTR);
// FIXME this doesn't work properly: trace is one instruction too short as
// tp is removed before all events were delivered
// trace WEATHER_NUMINSTR_TRACING instructions
// -> campaign-ready traces with identical lengths
bp.setWatchInstructionPointer(ANY_ADDR);
bp.setCounter(OOSTUBS_NUMINSTR);
#endif
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 (simulator.waitAny() == &ev_count) {
++instr_counter;
simulator.addEvent(&bp);
BPSingleEvent ev_count(ANY_ADDR);
simulator.addEvent(&ev_count);
}
log << dec << "tracing finished after " << instr_counter << " instructions" << endl;
// count instructions
// FIXME add SAL functionality for this?
int instr_counter = 0;
while (simulator.waitAny() == &ev_count) {
++instr_counter;
simulator.addEvent(&ev_count);
}
log << dec << "tracing finished after " << instr_counter << " instructions" << endl;
//TODO: safe this value for experiment STEP 3
simulator.removeFlow(&tp);
simulator.removeFlow(&tp);
// serialize trace to file
if (of.fail()) {
log << "failed to write " << tracefile << endl;
simulator.clearEvents(this);
return false;
// serialize trace to file
if (of.fail()) {
log << "failed to write " << tracefile << endl;
simulator.clearEvents(this);
return false;
}
of.close();
log << "trace written to " << tracefile << endl;
}
of.close();
log << "trace written to " << tracefile << endl;
#elif 1
#if 0
// STEP 3: The actual experiment.
#if !LOCAL
for (int i = 0; i < 400; ++i) { // more than 400 will be very slow (500 is max)