With the number of accessed memory addresses and the duration of the trace, we can deduce the size of the rectangular memory fault space. This will be used in testing.
176 lines
4.8 KiB
C++
176 lines
4.8 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <set>
|
|
#include "comm/TracePlugin.pb.h"
|
|
#include "util/ProtoStream.hpp"
|
|
#include "../../src/core/util/Logger.hpp"
|
|
#include "../../src/core/util/gzstream/gzstream.h"
|
|
#include "util/CommandLine.hpp"
|
|
|
|
using namespace fail;
|
|
using std::stringstream;
|
|
using std::endl;
|
|
using std::cout;
|
|
using std::cerr;
|
|
using std::hex;
|
|
using std::dec;
|
|
|
|
Logger LOG("dump-trace", true);
|
|
|
|
std::istream& openStream(const char *input_file,
|
|
std::ifstream& normal_stream, igzstream& gz_stream) {
|
|
normal_stream.open(input_file);
|
|
if (!normal_stream) {
|
|
LOG << "couldn't open " << input_file << endl;
|
|
exit(-1);
|
|
}
|
|
unsigned char b1, b2;
|
|
normal_stream >> b1 >> b2;
|
|
|
|
if (b1 == 0x1f && b2 == 0x8b) {
|
|
normal_stream.close();
|
|
gz_stream.open(input_file);
|
|
if (!gz_stream) {
|
|
LOG << "couldn't open " << input_file << endl;
|
|
exit(-1);
|
|
}
|
|
//LOG << "opened file " << input_file << " in GZip mode" << endl;
|
|
return gz_stream;
|
|
}
|
|
|
|
normal_stream.seekg(0);
|
|
|
|
//LOG << "opened file " << input_file << " in normal mode" << endl;
|
|
return normal_stream;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
Trace_Event ev;
|
|
|
|
CommandLine &cmd = CommandLine::Inst();
|
|
CommandLine::option_handle UNKNOWN =
|
|
cmd.addOption("", "", Arg::None, "usage: dump-trace [options] tracefile.tc");
|
|
CommandLine::option_handle HELP =
|
|
cmd.addOption("h", "help", Arg::None, "-h/--help \tPrint usage and exit");
|
|
CommandLine::option_handle STATS =
|
|
cmd.addOption("s", "stats", Arg::None,
|
|
"-s/--stats \tShow trace stats");
|
|
CommandLine::option_handle EXTENDED_TRACE =
|
|
cmd.addOption("", "extended-trace", Arg::None,
|
|
"--extended-trace \tDump extended trace information if available");
|
|
|
|
for (int i = 1; i < argc; ++i) {
|
|
cmd.add_args(argv[i]);
|
|
}
|
|
if (!cmd.parse()) {
|
|
std::cerr << "Error parsing arguments." << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
if (cmd[HELP] || cmd[UNKNOWN] || cmd.parser()->nonOptionsCount() != 1) {
|
|
for (option::Option* opt = cmd[UNKNOWN]; opt; opt = opt->next()) {
|
|
std::cerr << "Unknown option: " << opt->name << "\n";
|
|
}
|
|
for (int i = 1; i < cmd.parser()->nonOptionsCount(); ++i) {
|
|
std::cerr << "Unknown non-option: " << cmd.parser()->nonOption(i) << "\n";
|
|
}
|
|
cmd.printUsage();
|
|
if (cmd[HELP]) {
|
|
exit(0);
|
|
} else {
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
bool stats_only = cmd[STATS];
|
|
bool extended = cmd[EXTENDED_TRACE];
|
|
|
|
std::ifstream normal_stream;
|
|
igzstream gz_stream;
|
|
ProtoIStream ps(&openStream(cmd.parser()->nonOption(0), normal_stream, gz_stream));
|
|
|
|
uint64_t acctime = 0;
|
|
uint64_t stats_instr = 0, stats_reads = 0, stats_writes = 0;
|
|
uint64_t stats_read_b = 0, stats_write_b = 0, starttime = 0;
|
|
std::set<uint64_t> stats_mem_locations;
|
|
|
|
while (ps.getNext(&ev)) {
|
|
if (ev.has_time_delta()) {
|
|
if (!acctime) {
|
|
starttime = ev.time_delta();
|
|
}
|
|
acctime += ev.time_delta();
|
|
}
|
|
if (!ev.has_memaddr()) {
|
|
++stats_instr;
|
|
if (!stats_only) {
|
|
cout << "IP " << hex << ev.ip() << dec << " t=" << acctime << "\n";
|
|
}
|
|
} else {
|
|
stringstream ext;
|
|
if (ev.has_trace_ext() && !stats_only && extended) {
|
|
const Trace_Event_Extended& temp_ext = ev.trace_ext();
|
|
ext << " DATA " << std::hex;
|
|
ext << (uint64_t) temp_ext.data();
|
|
for (int i = 0; i < temp_ext.registers_size(); i++) {
|
|
const Trace_Event_Extended_Registers& temp_reg = temp_ext.registers(i);
|
|
ext << " REG "
|
|
<< (unsigned) temp_reg.id() << " = ";
|
|
if (temp_reg.has_value()) {
|
|
ext << (uint32_t) temp_reg.value();
|
|
} else {
|
|
ext << "??";
|
|
}
|
|
ext << " -> ";
|
|
if (temp_reg.has_value_deref()) {
|
|
ext << (uint32_t) temp_reg.value_deref();
|
|
} else {
|
|
ext << "??";
|
|
}
|
|
}
|
|
if (temp_ext.stack_size() > 0 ) {
|
|
ext << " STACK:";
|
|
for (int i = 0; i < temp_ext.stack_size(); i++) {
|
|
const Trace_Event_Extended_Stack& temp_stack = temp_ext.stack(i);
|
|
ext << " " << (uint32_t) temp_stack.value();
|
|
}
|
|
}
|
|
}
|
|
if (!stats_only) {
|
|
cout << "MEM "
|
|
<< (ev.accesstype() == Trace_Event_AccessType_READ ? "R" : "W") << " "
|
|
<< hex << ev.memaddr()
|
|
<< dec << " width " << ev.width()
|
|
<< hex << " IP " << ev.ip()
|
|
<< dec << " t=" << acctime
|
|
<< ext.str() << "\n";
|
|
} else {
|
|
for (uint64_t addr = ev.memaddr(); addr < ev.memaddr() + ev.width(); addr++){
|
|
stats_mem_locations.insert(addr);
|
|
}
|
|
}
|
|
if (ev.accesstype() == Trace_Event_AccessType_READ) {
|
|
stats_reads++;
|
|
stats_read_b += ev.width();
|
|
} else {
|
|
stats_writes++;
|
|
stats_write_b += ev.width();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (stats_only) {
|
|
cout << "#instructions: " << stats_instr << "\n"
|
|
<< "#memLocations: " << stats_mem_locations.size() << "\n"
|
|
<< "#memR: " << stats_reads << "\n"
|
|
<< "#memR_bytes: " << stats_read_b << "\n"
|
|
<< "#memW: " << stats_writes << "\n"
|
|
<< "#memW_bytes: " << stats_write_b << "\n"
|
|
<< "duration: " << (acctime - starttime + 1) << endl;
|
|
}
|
|
|
|
return 0;
|
|
}
|