273 lines
6.7 KiB
C++
273 lines
6.7 KiB
C++
|
|
#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++;
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|