Files
SAPFOR/src/Predictor/Lib/TraceLine.cpp

273 lines
6.7 KiB
C++
Raw Normal View History

2023-09-14 19:43:13 +03:00
#include <string.h>
#include <assert.h>
#include <memory>
#include <stdlib.h>
#include <fstream>
#include "TraceLine.h"
#include "ParseString.h"
#include "Ver.h"
#ifdef __GNUC__
#define _strdup strdup
#endif
using namespace std;
extern ofstream prot;
VectorTraceLine * traceLines; // lines from file, partially decoded
char * TraceLine::first_file_name = NULL;
int TraceLine::first_line_number = -1;
//bool VectorTraceLine::startStoreLinesRet = false;
//bool VectorTraceLine::startStoreLines = false;
// --------------------------------- TraceLine ---------------------------------------
// -------------------------------- CONSTRUCTORS -------------------------------------
TraceLine::TraceLine(char * buffer)
{
const int LINE_BUFFER_SIZE = 256;
char f_file[LINE_BUFFER_SIZE];
char f_name[LINE_BUFFER_SIZE];
char * fn_pos;
int str_len;
if (ParamFromString("TIME", func_time, buffer) &&
ParamFromString("LINE", source_line, buffer) &&
ParamFromString("FILE", f_file, buffer)) {
if ((fn_pos=strstr(buffer,"call_"))!=NULL) {
line_type = Call_;
fn_pos += strlen("Call_");
} else if ((fn_pos=strstr(buffer,"ret_"))!=NULL) {
line_type = Ret_;
fn_pos += strlen("Ret_");
} else if ((fn_pos=strstr(buffer,"Event_"))!=NULL) {
line_type = Event_;
fn_pos += strlen("Event_");;
} else
goto unknown;
str_len = strcspn(fn_pos," ");
strncpy(f_name, fn_pos, str_len);
f_name[str_len]='\0';
func_id = EventNameToID((string) f_name);
source_file =_strdup(f_file);
if (first_file_name == NULL) {
first_file_name = _strdup(f_file);
first_line_number = source_line;
}
info_line = _strdup(buffer); //was NULL
if (func_id == Unknown_Func)
{
#ifdef P_DEBUG
prot << " Warning : unknown function: " << f_name
<< " file = " << source_file
<< " line = " << source_line << endl;
#else
#endif
}
} else {
unknown:
func_time = 0.0;
source_line = 0;
source_file = NULL;
func_id = Unknown_Func;
source_file = NULL;
line_type = Unknown_;
info_line =_strdup(buffer);
}
}
// ---------------------------- COPY CONSTRACTOR -----------------------------------
TraceLine::TraceLine(TraceLine& tr) :
line_type(tr.line_type),
func_id(tr.func_id),
func_time(tr.func_time),
source_line(tr.source_line)
{
source_file = tr.source_file;
tr.source_file = NULL;
info_line = tr.info_line;
tr.info_line = NULL;
}
// -------------------------------- DESTRUCTOR -------------------------------------
TraceLine::~TraceLine()
{
if (source_file != NULL)
delete source_file;
if (info_line != NULL)
delete info_line;
}
// ------------------------------ VectorTraceLine ------------------------------------
// -------------------------------- CONSTRUCTOR --------------------------------------
VectorTraceLine::VectorTraceLine(char* file_name) :
endOfVector(false),
count(0),
size(0),
lines(NULL),
p_count(0),
p_size(0),
p_lines(NULL),
startStoreLines(false),
startStoreLinesRet(false)
{
// trace_file.open(file_name); //ZIP
if ((trace_file = gzopen(file_name, "rb")) == NULL) {
// if (!trace_file.is_open()) { //ZIP
cerr << "Can't open trace file '" << file_name << '\'' << endl;
// trace_file.exceptions(ostream::badbit | ostream::failbit | ostream::eofbit);
exit(1);
} else {
prot << " Reading/initial decoding of trace file..." << endl;
// read preamble lines
while (!startStoreLines && getLine())
;
getFrame();
prot << " Completed." << endl;
}
}
// -------------------------------- DESTRUCTOR -------------------------------------
VectorTraceLine::~VectorTraceLine()
{
for (int i = 0; i < size; i++)
delete lines[i];
free(lines);
//gzclose(trace_file);
}
bool VectorTraceLine::getLine()
{
const int LINE_BUFFER_SIZE = 256;
char buffer[LINE_BUFFER_SIZE];
int len;
int spn;
TraceLine * tmp;
// if (!trace_file)
if (trace_file == NULL)
return false;
else {
do {
// if (!trace_file.getline(buffer, LINE_BUFFER_SIZE)) {
if (gzgets(trace_file, buffer, LINE_BUFFER_SIZE) == Z_NULL) {
cerr << "Bad trace file" << endl;
prot << "Bad trace file" << endl;
exit(0);
}
len=strlen(buffer);
if ((buffer[len - 1] == 0x0a) && (buffer[len - 2] == 0x0d))
len -= 2;
else if (buffer[len - 1] == 0x0a)
len -= 1;
buffer[len] = 0;
spn=strspn(buffer," ");
} while ( len==0 ||
len==spn ||
(len==1 && *buffer==0x0d) ||
(strncmp(buffer+spn, "----------", 10) == 0));
tmp = new TraceLine(buffer + spn);
// control event dvm_exit
if (tmp->line_type == Event_) {
endOfVector = true;
return false;
}
if ((!startStoreLinesRet) && (tmp->line_type == Ret_) && (tmp->func_id == dvm_Init))
startStoreLinesRet = true;
if ((!startStoreLines) && (tmp->line_type == Call_) && startStoreLinesRet)
startStoreLines = true;
if (startStoreLines) {
// store trace line
lines = (TraceLine **) realloc(lines, sizeof(TraceLine *) * ++size);
lines[size - 1] = tmp;
} else {
// store preamble trace line
p_lines = (char **) realloc(p_lines, sizeof(char *) * ++p_size);
p_lines[p_size - 1] = tmp->info_line;
}
return true;
}
}
bool VectorTraceLine::getFrame()
{
if (lines[size - 1]->line_type == Call_) {
// next call exist in the trace file
int i;
// save last Call_ line from frame
TraceLine * tmp = new TraceLine(*lines[size - 1]);
// delete previouse frame;
for (i = 0; i < size; i++)
delete lines[i];
free(lines);
size = count = 0;
lines = NULL;
// store trace line Call_ in the object
lines = (TraceLine **) realloc(lines, sizeof(TraceLine *) * ++size);
lines[size - 1] = tmp;
// store the rest of the frame
while (getLine() && lines[size - 1]->line_type != Call_)
;
return true;
} else
return false;
}
TraceLine* VectorTraceLine::next()
{
count++;
if (count == size) {
// get next trace frame
if (getFrame()) {
return lines[++count];
} else
return NULL;
} else
return lines[count];
}
// ------------------------------ GetUnknownLines ------------------------------------
void VectorTraceLine::GetUnknownLines(int& il_count, char**& info_lines)
{
while ((count < size) && (lines[count]->line_type == Unknown_)) {
info_lines = (char**) realloc(info_lines, sizeof(char*) * (++il_count));
assert(info_lines != NULL);
info_lines[il_count-1] = _strdup(lines[count]->info_line);
count++;
}
}