#include #include #include #include #include #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++; } }