Merge branch 'tracing-off-by-one'

This commit is contained in:
Horst Schirmeier
2013-10-28 18:37:07 +01:00
4 changed files with 35 additions and 69 deletions

View File

@ -209,10 +209,6 @@ bool GenericTracing::run()
// this must be done *after* configuring the plugin: // this must be done *after* configuring the plugin:
simulator.addFlow(&tp); 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 // STEP 2: continue to the save point, and save state
if (start_symbol != save_symbol) { if (start_symbol != save_symbol) {

View File

@ -1,7 +1,6 @@
#include <iostream> #include <iostream>
#include <assert.h> #include <assert.h>
#include "sal/SALConfig.hpp"
#include "sal/SALInst.hpp" #include "sal/SALInst.hpp"
#include "sal/Register.hpp" #include "sal/Register.hpp"
#include "sal/Memory.hpp" #include "sal/Memory.hpp"
@ -11,46 +10,17 @@
using namespace std; using namespace std;
using namespace fail; 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() bool TracingPlugin::run()
{ {
MemoryManager& mm = simulator.getMemoryManager(); MemoryManager& mm = simulator.getMemoryManager();
MemAccessListener ev_mem(ANY_ADDR); MemAccessListener ev_mem(ANY_ADDR);
BPSingleListener ev_step(ANY_ADDR); BPSingleListener ev_step(ANY_ADDR);
BaseListener *ev; BaseListener *ev = 0;
if (m_iponly || !m_memonly) { // ev_step is added in the first loop iteration
simulator.addListener(&ev_step);
} if (m_tracetype | TRACE_MEM) {
if (m_memonly || !m_iponly) {
simulator.addListener(&ev_mem); simulator.addListener(&ev_mem);
} }
if(m_protoStreamFile) { if(m_protoStreamFile) {
@ -62,18 +32,20 @@ bool TracingPlugin::run()
// the first event gets an absolute time stamp, all others a delta to their // the first event gets an absolute time stamp, all others a delta to their
// predecessor // predecessor
simtime_t prevtime = 0, curtime;
simtime_diff_t deltatime; simtime_diff_t deltatime;
bool first = true;
while (true) { while (true) {
ev = simulator.resume(); curtime = simulator.getTimerTicks();
deltatime = curtime - prevtime;
m_curtime = simulator.getTimerTicks(); if (ev == &ev_step || (first && (m_tracetype | TRACE_IP))) {
deltatime = m_curtime - m_prevtime; first = false;
if (ev == &ev_step) {
simulator.addListener(&ev_step); simulator.addListener(&ev_step);
address_t ip = simulator.getCPU(0).getInstructionPointer();
address_t ip = ev_step.getTriggerInstructionPointer();
if (m_ipMap && !m_ipMap->isMatching(ip)) { if (m_ipMap && !m_ipMap->isMatching(ip)) {
continue; continue;
} }
@ -86,6 +58,10 @@ bool TracingPlugin::run()
// only store deltas != 0 // only store deltas != 0
if (deltatime != 0) { if (deltatime != 0) {
e.set_time_delta(deltatime); 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); ps->writeMessage(&e);
} }
@ -116,6 +92,10 @@ bool TracingPlugin::run()
// only store deltas != 0 // only store deltas != 0
if (deltatime != 0) { if (deltatime != 0) {
e.set_time_delta(deltatime); 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 /* When we're doing a full trace, we log more data in
@ -143,14 +123,12 @@ bool TracingPlugin::run()
ps->writeMessage(&e); ps->writeMessage(&e);
} }
} else { } else if (!first) {
if (m_os) if (m_os)
*m_os << "[Tracing] SOMETHING IS SERIOUSLY WRONG\n"; *m_os << "[Tracing] SOMETHING IS SERIOUSLY WRONG\n";
} }
// do this only if the last delta was written ev = simulator.resume();
// (no, e.g., memory map mismatch)
m_prevtime = m_curtime;
} }
return true; return true;

View File

@ -7,8 +7,6 @@
#include "util/ProtoStream.hpp" #include "util/ProtoStream.hpp"
#include "efw/ExperimentFlow.hpp" #include "efw/ExperimentFlow.hpp"
#include "config/FailConfig.hpp" #include "config/FailConfig.hpp"
#include "sal/Listener.hpp"
#include "TracePlugin.pb.h" #include "TracePlugin.pb.h"
@ -42,22 +40,18 @@ class TracingPlugin : public fail::ExperimentFlow
private: private:
fail::MemoryMap *m_memMap; //!< address restriction for memory accesses fail::MemoryMap *m_memMap; //!< address restriction for memory accesses
fail::MemoryMap *m_ipMap; //!< instruction address restriction fail::MemoryMap *m_ipMap; //!< instruction address restriction
bool m_memonly; //!< log instructions only if they are memory accesses //! trace nothing / instructions / mem accesses / both (can be bitwise ORed)
bool m_iponly; //!< log instruction addresses only 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) bool m_full_trace; //!< do a full trace (more information for the events)
std::ostream *m_protoStreamFile; std::ostream *m_protoStreamFile;
std::ostream *m_os; //!< ostream to write human-readable trace into std::ostream *m_os; //!< ostream to write human-readable trace into
fail::ProtoOStream *ps; fail::ProtoOStream *ps;
fail::simtime_t m_prevtime;
fail::simtime_t m_curtime;
public: public:
TracingPlugin(bool full_trace = false) TracingPlugin(bool full_trace = false)
: m_memMap(0), m_ipMap(0), m_memonly(false), m_iponly(false), : m_memMap(0), m_ipMap(0), m_tracetype(TRACE_BOTH),
m_full_trace(full_trace), m_protoStreamFile(0), m_os(0), m_full_trace(full_trace), m_protoStreamFile(0), m_os(0) { }
m_prevtime(0) { }
bool run(); bool run();
/** /**
* Restricts tracing to memory addresses listed in this MemoryMap. An * 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 * conducted a memory access. Defaults to false: All instructions are
* logged. * 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. * 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. * If invoked with fulltrace=true, a extended (full) trace is done.
*/ */
@ -94,13 +88,6 @@ public:
* ProtoStream file to trace into (trace.proto instance) * ProtoStream file to trace into (trace.proto instance)
*/ */
void setTraceFile(std::ostream *os) { m_protoStreamFile = os; } 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__ #endif // __TRACING_PLUGIN_HPP__

View File

@ -66,6 +66,8 @@ bool Importer::copy_to_database(fail::ProtoIStream &ps) {
// instruction counter within trace // instruction counter within trace
instruction_count_t instr = 0; instruction_count_t instr = 0;
// instruction counter new memory access events belong to
instruction_count_t instr_memaccess = 0;
// the currently processed event // the currently processed event
Trace_Event ev; 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; LOG << "error: instruction_count_t overflow, aborting at instr=" << instr << std::endl;
return false; return false;
} }
/* Another instruction was executed, handle it in the /* Another instruction was executed, handle it in the
subclass */ subclass */
if (!handle_ip_event(curtime, instr, ev)) { if (!handle_ip_event(curtime, instr, ev)) {
@ -99,10 +102,12 @@ bool Importer::copy_to_database(fail::ProtoIStream &ps) {
return false; return false;
} }
// all subsequent mem access events belong to this dynamic instr
instr_memaccess = instr;
instr++; instr++;
} else { } else {
if (!handle_mem_event(curtime, instr, ev)) { if (!handle_mem_event(curtime, instr_memaccess, ev)) {
LOG << "error: handle_mem_event() failed at instr=" << instr << std::endl; LOG << "error: handle_mem_event() failed at instr=" << instr_memaccess << std::endl;
return false; return false;
} }
} }