X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Fltt%2Fconvert%2Fconvert.c;h=3f7bc1415fbf3d69d7ad9281a3409312f9899712;hb=09a33c9a2bc6795df9349a7355167ecaa588343b;hp=e02944efb120e2360a6bcaa23c70c7c274c80858;hpb=43da6a594b6344036fbc1bdf259b514a11bfb670;p=lttv.git diff --git a/ltt/branches/poly/ltt/convert/convert.c b/ltt/branches/poly/ltt/convert/convert.c index e02944ef..3f7bc141 100644 --- a/ltt/branches/poly/ltt/convert/convert.c +++ b/ltt/branches/poly/ltt/convert/convert.c @@ -1,8 +1,11 @@ #include +#include #include #include #include -#include +#include +#include +#include #include #include "LTTTypes.h" @@ -13,7 +16,7 @@ #define PROCESS_EXIT_ID 21 #define INFO_ENTRY 9 -#define OVERFLOW_FIGURE 4294967296 +#define OVERFLOW_FIGURE 0x100000000ULL typedef struct _new_process { @@ -30,10 +33,14 @@ do\ int readFile(int fd, void * buf, size_t size, char * mesg) { - ssize_t nbBytes; - nbBytes = read(fd, buf, size); - if(nbBytes != size){ - printf("%s\n",mesg); + ssize_t nbBytes = read(fd, buf, size); + + if((size_t)nbBytes != size) { + if(nbBytes < 0) { + perror("Error in readFile : "); + } else { + printf("%s\n",mesg); + } exit(1); } return 0; @@ -68,6 +75,14 @@ typedef struct _buffer_start{ uint32_t block_id; } __attribute__ ((packed)) buffer_start; +typedef struct _buffer_end{ + uint32_t seconds; + uint32_t nanoseconds; + uint64_t cycle_count; + uint32_t block_id; +} __attribute__ ((packed)) buffer_end; + + typedef struct _heartbeat{ uint32_t seconds; uint32_t nanoseconds; @@ -92,12 +107,13 @@ int main(int argc, char ** argv){ char hardware_platform[BUFFER_SIZE]; char operating_system[BUFFER_SIZE]; int cpu; - int ltt_block_size; - int ltt_major_version; - int ltt_minor_version; + int ltt_block_size=0; + int ltt_major_version=0; + int ltt_minor_version=0; int ltt_log_cpu; + guint ltt_trace_start_size; char buf[BUFFER_SIZE]; - int i,j, k; + int i, k; uint8_t cpu_id; @@ -118,26 +134,29 @@ int main(int argc, char ** argv){ char * buffer, *buf_out, cpuStr[4*BUFFER_SIZE]; char * buf_fac, * buf_intr, * buf_proc; void * write_pos, *write_pos_fac, * write_pos_intr, *write_pos_proc; - trace_start *tStart; + trace_start_any *tStart; trace_buffer_start *tBufStart; trace_buffer_end *tBufEnd; trace_file_system * tFileSys; uint16_t newId, startId, tmpId; uint8_t evId; - uint32_t time_delta, startTimeDelta, previous_time_delta; + uint32_t time_delta, startTimeDelta; void * cur_pos, *end_pos; buffer_start start, start_proc, start_intr; - buffer_start end, end_proc, end_intr; + buffer_end end, end_proc, end_intr; heartbeat beat; - int beat_count = 0; + uint64_t adaptation_tsc; // (Mathieu) uint32_t size_lost; - int reserve_size = sizeof(buffer_start) + sizeof(uint16_t) + 2*sizeof(uint32_t);//lost_size and buffer_end event + int reserve_size = sizeof(buffer_start) + + sizeof(buffer_end) + //buffer_end event + sizeof(uint32_t); //lost size int nb_para; new_process process; if(argc < 4){ - printf("Not enough parameters\n"); + printf("Usage : ./convert processfile_name number_of_cpu tracefile1 tracefile2 ... trace_creation_directory\n"); + printf("For more details, see README.\n"); exit(1); } @@ -274,28 +293,70 @@ int main(int argc, char ** argv){ cur_pos += sizeof(uint16_t); //Skip event size evId = *(uint8_t *)cur_pos; - cur_pos += sizeof(uint8_t); - cur_pos += sizeof(uint32_t); - tStart = (trace_start*)cur_pos; + g_assert(evId == TRACE_START); + cur_pos += sizeof(uint8_t); //skip EvId + cur_pos += sizeof(uint32_t); //skip time delta + tStart = (trace_start_any*)cur_pos; + if(tStart->MagicNumber != TRACER_MAGIC_NUMBER) + g_error("Trace magic number does not match : %lx, should be %lx", + tStart->MagicNumber, TRACER_MAGIC_NUMBER); + if(tStart->MajorVersion != TRACER_SUP_VERSION_MAJOR) + g_error("Trace Major number does match : %hu, should be %u", + tStart->MajorVersion, TRACER_SUP_VERSION_MAJOR); startId = newId; startTimeDelta = time_delta; start.seconds = tBufStart->Time.tv_sec; - start.nanoseconds = tBufStart->Time.tv_usec; + /* Fix (Mathieu) */ + start.nanoseconds = tBufStart->Time.tv_usec * 1000; start.cycle_count = tBufStart->TSC; start.block_id = tBufStart->ID; end.block_id = start.block_id; - ltt_major_version = tStart->MajorVersion; - ltt_minor_version = tStart->MinorVersion; - ltt_block_size = tStart->BufferSize; - ltt_log_cpu = tStart->LogCPUID; - block_size = ltt_block_size; - block_number = file_size/block_size; + g_printf("Trace version %hu.%hu detected\n", + tStart->MajorVersion, + tStart->MinorVersion); + if(tStart->MinorVersion == 2) { + trace_start_2_2* tStart_2_2 = (trace_start_2_2*)tStart; + ltt_major_version = tStart_2_2->MajorVersion; + ltt_minor_version = tStart_2_2->MinorVersion; + ltt_block_size = tStart_2_2->BufferSize; + ltt_log_cpu = tStart_2_2->LogCPUID; + ltt_trace_start_size = sizeof(trace_start_2_2); + /* Verify if it's a broken 2.2 format */ + if(*(uint8_t*)(cur_pos + sizeof(trace_start_2_2)) == 0) { + /* Cannot have two trace start events. We cannot detect the problem + * if the flight recording flag is set to 1, as it conflicts + * with TRACE_SYSCALL_ENTRY. + */ + g_warning("This is a 2.3 trace format that has a 2.2 tag. Please upgrade your kernel"); + g_printf("Processing the trace as a 2.3 format\n"); + + tStart->MinorVersion = 3; + } + } + + if(tStart->MinorVersion == 3) { + trace_start_2_3* tStart_2_3 = (trace_start_2_3*)tStart; + ltt_major_version = tStart_2_3->MajorVersion; + ltt_minor_version = tStart_2_3->MinorVersion; + ltt_block_size = tStart_2_3->BufferSize; + ltt_log_cpu = tStart_2_3->LogCPUID; + ltt_trace_start_size = sizeof(trace_start_2_3); + /* We do not use the flight recorder information for now, because we + * never use the .proc file anyway */ + } else { + ltt_trace_start_size = 0; + g_error("Minor version unknown : %hu. Supported minors : 2, 3", + tStart->MinorVersion); + } + + block_size = ltt_block_size;//FIXME + block_number = file_size/ltt_block_size; g_free(buffer); - buffer = g_new(char, block_size); + buffer = g_new(char, ltt_block_size); buf_fac = g_new(char, block_size); write_pos_fac = buf_fac; buf_intr = g_new(char, block_size); @@ -305,14 +366,13 @@ int main(int argc, char ** argv){ buf_out = g_new(char, block_size); write_pos = buf_out; - sprintf(cpuStr,"%s/%d\0",foo_cpu,k); + sprintf(cpuStr,"%s/%d",foo_cpu,k); fdCpu = open(cpuStr, O_CREAT | O_RDWR | O_TRUNC,S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH); //for cpu k if(fdCpu < 0) g_error("Unable to open cpu file %d\n", k); lseek(fd,0,SEEK_SET); for(i=0;iTime.tv_sec; - start.nanoseconds = tBufStart->Time.tv_usec; - start.cycle_count = tBufStart->TSC; + /* usec -> nsec (Mathieu) */ + start.nanoseconds = tBufStart->Time.tv_usec * 1000; start.block_id = tBufStart->ID; end.block_id = start.block_id; - end_pos = buffer + block_size; //end of the buffer + end_pos = buffer + ltt_block_size; //end of the buffer size_lost = *(uint32_t*)(end_pos - sizeof(uint32_t)); - end_pos = buffer + block_size - size_lost ; //buffer_end event + end_pos = buffer + ltt_block_size - size_lost ; //buffer_end event if(ltt_log_cpu){ tBufEnd = (trace_buffer_end*)(end_pos + 2 * sizeof(uint8_t)+sizeof(uint32_t)); }else{ tBufEnd = (trace_buffer_end*)(end_pos+sizeof(uint8_t)+sizeof(uint32_t)); } end.seconds = tBufEnd->Time.tv_sec; - end.nanoseconds = tBufEnd->Time.tv_usec; - end.cycle_count = tBufEnd->TSC; + /* usec -> nsec (Mathieu) */ + end.nanoseconds = tBufEnd->Time.tv_usec * 1000; + // only 32 bits :( + //end.cycle_count = tBufEnd->TSC; //skip buffer start and trace start events - if(i==0) //the first block - cur_pos = buffer + sizeof(trace_buffer_start) + sizeof(trace_start) + 2*(sizeof(uint8_t)+sizeof(uint16_t)+sizeof(uint32_t)); - else //other blocks - cur_pos = buffer + sizeof(trace_buffer_start) + sizeof(uint8_t)+sizeof(uint16_t)+sizeof(uint32_t); - + if(i==0) { + //the first block + adaptation_tsc = (uint64_t)tBufStart->TSC; + cur_pos = buffer + sizeof(trace_buffer_start) + + ltt_trace_start_size + + 2*(sizeof(uint8_t) + + sizeof(uint16_t)+sizeof(uint32_t)); + } else { + //other blocks + cur_pos = buffer + sizeof(trace_buffer_start) + + sizeof(uint8_t) + + sizeof(uint16_t)+sizeof(uint32_t); + + /* Fix (Mathieu) */ + if(time_delta < (0xFFFFFFFFULL&adaptation_tsc)) { + /* Overflow */ + adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + + 0x100000000ULL + + (uint64_t)time_delta; + } else { + /* No overflow */ + adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + time_delta; + } + + } + start.cycle_count = adaptation_tsc; + //write start block event write_to_buffer(write_pos,(void*)&startId, sizeof(uint16_t)); write_to_buffer(write_pos,(void*)&startTimeDelta, sizeof(uint32_t)); @@ -436,27 +519,56 @@ int main(int argc, char ** argv){ cur_pos += sizeof(uint8_t); time_delta = *(uint32_t*)cur_pos; cur_pos += sizeof(uint32_t); - - if(time_delta < previous_time_delta){ - end.cycle_count += OVERFLOW_FIGURE; - } - previous_time_delta = time_delta; + //write event_id and time_delta write_to_buffer(write_pos,(void*)&newId,sizeof(uint16_t)); write_to_buffer(write_pos,(void*)&time_delta, sizeof(uint32_t)); - + + /* Fix (Mathieu) */ + if(time_delta < (0xFFFFFFFFULL&adaptation_tsc)) { + /* Overflow */ + adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + 0x100000000ULL + + (uint64_t)time_delta; + } else { + /* No overflow */ + adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + time_delta; + } + + if(evId == TRACE_BUFFER_END){ - int size = block_size + ((void*)buf_out - write_pos)+ sizeof(uint16_t) + sizeof(uint32_t); - write_to_buffer(write_pos,(void*)&end,sizeof(buffer_start)); +#if 0 + /* Fix (Mathieu) */ + if(time_delta < (0xFFFFFFFFULL&adaptation_tsc)) { + /* Overflow */ + adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + 0x100000000ULL + + (uint64_t)time_delta; + } else { + /* No overflow */ + adaptation_tsc = (adaptation_tsc&0xFFFFFFFF00000000ULL) + time_delta; + } +#endif //0 + end.cycle_count = adaptation_tsc; + int size = (void*)buf_out + block_size - write_pos + - sizeof(buffer_end) - sizeof(uint32_t); + + /* size _lost_ ? */ + //int size = (void*)buf_out + block_size - write_pos + // + sizeof(uint16_t) + sizeof(uint32_t); + g_assert((void*)write_pos < (void*)buf_out + block_size); + write_to_buffer(write_pos,(void*)&end,sizeof(buffer_end)); write_pos = buf_out + block_size - sizeof(uint32_t); write_to_buffer(write_pos,(void*)&size, sizeof(uint32_t)); write(fdCpu,(void*)buf_out, block_size); //write out processes and intrrupts files { - int size_intr = block_size - (write_pos_intr - (void*)buf_intr); - int size_proc = block_size - (write_pos_proc - (void*)buf_proc); + int size_intr = block_size + (void*)buf_intr - write_pos_intr + - sizeof(buffer_end) - sizeof(uint32_t); + int size_proc = block_size + (void*)buf_proc - write_pos_proc + - sizeof(buffer_end) - sizeof(uint32_t); + //int size_intr = block_size - (write_pos_intr - (void*)buf_intr); + //int size_proc = block_size - (write_pos_proc - (void*)buf_proc); write_to_buffer(write_pos_intr,(void*)&newId,sizeof(uint16_t)); write_to_buffer(write_pos_intr,(void*)&time_delta, sizeof(uint32_t)); end_intr = end; @@ -553,19 +665,16 @@ int main(int argc, char ** argv){ event_size = sizeof(trace_network); break; case TRACE_HEARTBEAT: - beat_count++; beat.seconds = 0; beat.nanoseconds = 0; - beat.cycle_count = start.cycle_count + beat_count * OVERFLOW_FIGURE; + beat.cycle_count = adaptation_tsc; event_size = 0; - - // end.cycle_count += OVERFLOW_FIGURE; write_to_buffer(write_pos_intr,(void*)&newId, sizeof(uint16_t)); - write_to_buffer(write_pos_intr,(void*)&timeDelta, sizeof(uint32_t)); + write_to_buffer(write_pos_intr,(void*)&time_delta, sizeof(uint32_t)); write_to_buffer(write_pos_intr,(void*)&beat, sizeof(heartbeat)); write_to_buffer(write_pos_proc,(void*)&newId, sizeof(uint16_t)); - write_to_buffer(write_pos_proc,(void*)&timeDelta, sizeof(uint32_t)); + write_to_buffer(write_pos_proc,(void*)&time_delta, sizeof(uint32_t)); write_to_buffer(write_pos_proc,(void*)&beat, sizeof(heartbeat)); break; default: @@ -644,5 +753,8 @@ int main(int argc, char ** argv){ close(fdProc); fclose(fp); + g_printf("Conversion completed. Don't forget to copy core.xml to eventdefs directory\n"); + + return 0; }