diff --git a/src/experiments/generic-tracing/experiment.cc b/src/experiments/generic-tracing/experiment.cc index 553a9056..0d57f049 100644 --- a/src/experiments/generic-tracing/experiment.cc +++ b/src/experiments/generic-tracing/experiment.cc @@ -209,10 +209,6 @@ bool GenericTracing::run() // this must be done *after* configuring the plugin: simulator.addFlow(&tp); - // In order to not loose the IP event at the beginning of the - // trace, we have to handle the IP event manually - tp.handleSingleIP(l_start_symbol); - //////////////////////////////////////////////////////////////// // STEP 2: continue to the save point, and save state if (start_symbol != save_symbol) { diff --git a/src/plugins/tracing/TracingPlugin.cc b/src/plugins/tracing/TracingPlugin.cc index 055fe994..c74f7ee5 100644 --- a/src/plugins/tracing/TracingPlugin.cc +++ b/src/plugins/tracing/TracingPlugin.cc @@ -1,7 +1,6 @@ #include #include -#include "sal/SALConfig.hpp" #include "sal/SALInst.hpp" #include "sal/Register.hpp" #include "sal/Memory.hpp" @@ -11,46 +10,17 @@ using namespace std; using namespace fail; -void TracingPlugin::handleSingleIP(const BPListener &bp) { - address_t ip = bp.getTriggerInstructionPointer(); - if (m_ipMap && !m_ipMap->isMatching(ip)) { - return; - } - - m_curtime = simulator.getTimerTicks(); - simtime_diff_t deltatime = m_curtime - m_prevtime; - - if (m_os) - *m_os << "[Tracing] IP " << hex << ip << "\n"; - - if (m_protoStreamFile) { - Trace_Event e; - e.set_ip(ip); - // only store deltas != 0 - if (deltatime != 0) { - e.set_time_delta(deltatime); - } - if (!ps) { - ps = new ProtoOStream (m_protoStreamFile); - } - - ps->writeMessage(&e); - } -} - - bool TracingPlugin::run() { MemoryManager& mm = simulator.getMemoryManager(); MemAccessListener ev_mem(ANY_ADDR); BPSingleListener ev_step(ANY_ADDR); - BaseListener *ev; + BaseListener *ev = 0; - if (m_iponly || !m_memonly) { - simulator.addListener(&ev_step); - } - if (m_memonly || !m_iponly) { + // ev_step is added in the first loop iteration + + if (m_tracetype | TRACE_MEM) { simulator.addListener(&ev_mem); } if(m_protoStreamFile) { @@ -62,18 +32,20 @@ bool TracingPlugin::run() // the first event gets an absolute time stamp, all others a delta to their // predecessor + simtime_t prevtime = 0, curtime; simtime_diff_t deltatime; + bool first = true; + while (true) { - ev = simulator.resume(); + curtime = simulator.getTimerTicks(); + deltatime = curtime - prevtime; - m_curtime = simulator.getTimerTicks(); - deltatime = m_curtime - m_prevtime; - - if (ev == &ev_step) { + if (ev == &ev_step || (first && (m_tracetype | TRACE_IP))) { + first = false; simulator.addListener(&ev_step); + address_t ip = simulator.getCPU(0).getInstructionPointer(); - address_t ip = ev_step.getTriggerInstructionPointer(); if (m_ipMap && !m_ipMap->isMatching(ip)) { continue; } @@ -86,6 +58,10 @@ bool TracingPlugin::run() // only store deltas != 0 if (deltatime != 0) { e.set_time_delta(deltatime); + + // do this only if the last delta was written + // (no, e.g., memory map mismatch) + prevtime = curtime; } ps->writeMessage(&e); } @@ -116,6 +92,10 @@ bool TracingPlugin::run() // only store deltas != 0 if (deltatime != 0) { e.set_time_delta(deltatime); + + // do this only if the last delta was written + // (no, e.g., memory map mismatch) + prevtime = curtime; } /* When we're doing a full trace, we log more data in @@ -143,14 +123,12 @@ bool TracingPlugin::run() ps->writeMessage(&e); } - } else { + } else if (!first) { if (m_os) *m_os << "[Tracing] SOMETHING IS SERIOUSLY WRONG\n"; } - // do this only if the last delta was written - // (no, e.g., memory map mismatch) - m_prevtime = m_curtime; + ev = simulator.resume(); } return true; diff --git a/src/plugins/tracing/TracingPlugin.hpp b/src/plugins/tracing/TracingPlugin.hpp index de9bb026..1004e949 100644 --- a/src/plugins/tracing/TracingPlugin.hpp +++ b/src/plugins/tracing/TracingPlugin.hpp @@ -7,8 +7,6 @@ #include "util/ProtoStream.hpp" #include "efw/ExperimentFlow.hpp" #include "config/FailConfig.hpp" -#include "sal/Listener.hpp" - #include "TracePlugin.pb.h" @@ -42,22 +40,18 @@ class TracingPlugin : public fail::ExperimentFlow private: fail::MemoryMap *m_memMap; //!< address restriction for memory accesses fail::MemoryMap *m_ipMap; //!< instruction address restriction - bool m_memonly; //!< log instructions only if they are memory accesses - bool m_iponly; //!< log instruction addresses only + //! trace nothing / instructions / mem accesses / both (can be bitwise ORed) + enum { TRACE_NONE = 0, TRACE_IP, TRACE_MEM, TRACE_BOTH } m_tracetype; bool m_full_trace; //!< do a full trace (more information for the events) std::ostream *m_protoStreamFile; std::ostream *m_os; //!< ostream to write human-readable trace into fail::ProtoOStream *ps; - fail::simtime_t m_prevtime; - fail::simtime_t m_curtime; - public: TracingPlugin(bool full_trace = false) - : m_memMap(0), m_ipMap(0), m_memonly(false), m_iponly(false), - m_full_trace(full_trace), m_protoStreamFile(0), m_os(0), - m_prevtime(0) { } + : m_memMap(0), m_ipMap(0), m_tracetype(TRACE_BOTH), + m_full_trace(full_trace), m_protoStreamFile(0), m_os(0) { } bool run(); /** * Restricts tracing to memory addresses listed in this MemoryMap. An @@ -77,11 +71,11 @@ public: * conducted a memory access. Defaults to false: All instructions are * logged. */ - void setLogMemOnly(bool memonly) { m_memonly = memonly; } + void setLogMemOnly(bool memonly = true) { m_tracetype = memonly ? TRACE_MEM : TRACE_BOTH; } /** * If invoked with iponly=true, only instruction addresses are logged. */ - void setLogIPOnly(bool iponly) { m_iponly = iponly; } + void setLogIPOnly(bool iponly = true) { m_tracetype = iponly ? TRACE_IP : TRACE_BOTH; } /** * If invoked with fulltrace=true, a extended (full) trace is done. */ @@ -94,13 +88,6 @@ public: * ProtoStream file to trace into (trace.proto instance) */ void setTraceFile(std::ostream *os) { m_protoStreamFile = os; } - - /** - * Handles a single IP event. This is important for starting the - * tracing process after triggering a breakpoint. Just pass on the - * breakpoint - */ - void handleSingleIP(const fail::BPListener &bp); }; #endif // __TRACING_PLUGIN_HPP__ diff --git a/tools/import-trace/Importer.cc b/tools/import-trace/Importer.cc index accc562f..ab02e53e 100644 --- a/tools/import-trace/Importer.cc +++ b/tools/import-trace/Importer.cc @@ -66,6 +66,8 @@ bool Importer::copy_to_database(fail::ProtoIStream &ps) { // instruction counter within trace instruction_count_t instr = 0; + // instruction counter new memory access events belong to + instruction_count_t instr_memaccess = 0; // the currently processed event Trace_Event ev; @@ -92,6 +94,7 @@ bool Importer::copy_to_database(fail::ProtoIStream &ps) { LOG << "error: instruction_count_t overflow, aborting at instr=" << instr << std::endl; return false; } + /* Another instruction was executed, handle it in the subclass */ if (!handle_ip_event(curtime, instr, ev)) { @@ -99,10 +102,12 @@ bool Importer::copy_to_database(fail::ProtoIStream &ps) { return false; } + // all subsequent mem access events belong to this dynamic instr + instr_memaccess = instr; instr++; } else { - if (!handle_mem_event(curtime, instr, ev)) { - LOG << "error: handle_mem_event() failed at instr=" << instr << std::endl; + if (!handle_mem_event(curtime, instr_memaccess, ev)) { + LOG << "error: handle_mem_event() failed at instr=" << instr_memaccess << std::endl; return false; } }