T32SIM: Integrating Tracing feature of the T32SIM.

After each simulator break, T32Tracer retrieves the latest (16)
trace records from the T32. Memory address and value can now
be evaluated easily from the trace record.

TODO:Nevertheless we still have to traverse the trace to
find the instruction causing the access.
This commit is contained in:
Martin Hoffmann
2013-03-21 17:59:21 +01:00
parent 4e8098a636
commit b8e706b1a5
17 changed files with 270 additions and 26 deletions

View File

@ -1,6 +1,8 @@
set(SRCS
main.cc
T32Connector.cc
T32TraceFormat.cc
T32Tracer.cc
)
add_executable(fail-client ${SRCS})
@ -10,3 +12,4 @@ install(TARGETS fail-client RUNTIME DESTINATION bin)
add_executable(t32cli t32cli.cc)
target_link_libraries(t32cli t32api)

View File

@ -78,7 +78,7 @@ int T32Connector::getState() const {
void T32Connector::showMemoryRegions(const memory_map_t& map) const {
for(int i = 0; i < map.size(); i++){
for(unsigned int i = 0; i < map.size(); i++){
std::cout << "[" << i << "] 0x" << std::hex << map[i].first << " - 0x" << std::hex << map[i].second << std::endl;
}
}

View File

@ -0,0 +1,25 @@
#include "T32TraceFormat.hpp"
#include <iostream>
using namespace std;
namespace fail {
std::ostream& operator <<(std::ostream & os, const fail::T32TraceRecord & r) {
#ifndef __puma
if(r.isDataWrite()){
os << "WRITE";
} else if (r.isDataRead()) {
os << "READ";
} else if( r.isProgram()) {
os << "PROGRAM";
} else {
os << "UNKNOWN";
}
os << "\t" << hex << (int)(r.getAddress()) << "\t" << r.getData() << "\t";
#endif
return os;
}
}; // end of namespace

View File

@ -0,0 +1,66 @@
#include "T32Tracer.hpp"
#include "T32TraceFormat.hpp"
#include <fstream>
#include <iostream>
#include "t32.h"
using namespace std;
namespace fail {
T32Tracer::T32Tracer( const std::string& tfile ) : path(tfile), m_log("T32Tracer", false) {
// TODO Check if tracing is available:
avail = true;
exportcmd = "Trace.export " + path;
m_log << "Trace file: " << path.c_str() << endl;
}
void T32Tracer::setup() const {
T32_Cmd("Trace.SIZE 16."); // trace 16 records
T32_Cmd("Trace.METHOD Analyzer");
T32_Cmd("Trace.autoarm on");
T32_Cmd("Trace.autoinit on");
T32_Cmd("Trace.state");
}
int T32Tracer::evaluate(){
// clear old records
rvec.clear();
// export trace to file
//T32_Cmd(static_cast<char*>(exportcmd.c_str()));
T32_Cmd((char*)(exportcmd.c_str()));
// open trace file.
ifstream tracefile;
tracefile.open(path.c_str(), ios::in | ios::binary);
if(tracefile.is_open()){
// evaluate trace.
T32TraceHeader hdr;
tracefile.seekg(0, ios::beg);
tracefile.read(reinterpret_cast<char*>(&hdr), sizeof(T32TraceHeader));
T32TraceRecord r;
for(size_t i = 0; i < hdr.number_of_records; ++i) {
tracefile.read(reinterpret_cast<char*>(&r), sizeof(T32TraceRecord));
rvec.push_back(r); // add trace record to vector
}
return rvec.size();
}
return -1;
}
bool T32Tracer::wasDataAccess(void) const {
// TODO if rvec.size() != 0 !!
return rvec.back().isDataAccess();
}
void T32Tracer::dump(void){
for(size_t i = 0; i < rvec.size(); ++i) {
m_log << "[" << dec << i << "] " << rvec[i] << endl;
}
}
}; // end of namespace fail

View File

@ -22,6 +22,7 @@
#include "util/optionparser/optionparser_ext.hpp"
#include "T32Connector.hpp"
#include "T32Tracer.hpp"
#include "t32config.hpp"
#include "sal/MemoryInstruction.hpp"
#include "util/Disassembler.hpp"
@ -54,7 +55,6 @@ int main(int argc, char** argv){
option::Option options[stats.options_max], buffer[stats.buffer_max];
option::Parser parse(usage, argc, argv, options, buffer);
return 0;
if (parse.error()){
cerr << "Error parsing arguments." << endl;
return 1;
@ -101,18 +101,27 @@ int main(int argc, char** argv){
MemoryInstruction mem;
address_t ip;
// Enable T32 Tracer (if available)
T32Tracer tr("/tmp/tr.x"); // TODO configurable trace file path
tr.setup(); // enable and configure tracing.
while(1) {
// Start execution (with next timeout, if any)
t32.go();
// Wait for debugger to stop.
while( t32.isRunning() ) {}
// Evaluate state.
t32.test();// TODO
// Call appropriate callback of the SimulatorController.
ip = fail::simulator.getCPU(0).getInstructionPointer();
fail::simulator.onBreakpoint(&fail::simulator.getCPU(0), ip , fail::ANY_ADDR);
if( meminstruction.eval(ip, mem) ) {
fail::simulator.onMemoryAccess(&fail::simulator.getCPU(0), mem.getAddress(), mem.getWidth(), mem.isWriteAccess(), ip );
// Evaluate tracing result, handle memory access event..
if((tr.evaluate() > 0) && (tr.wasDataAccess())){
// TODO: step back in trace and find program counter of the according instruction.
// ip = XXX;
fail::simulator.onMemoryAccess(&fail::simulator.getCPU(0), tr.getLatestRecord().getAddress(), /* TODO access width: */ 4, tr.getLatestRecord().isDataWrite(), ip );
tr.dump();
}
}