+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
+#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <linux/errno.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
#include <glib.h>
#include "LTTTypes.h"
#define PROCESS_EXIT_ID 21
#define INFO_ENTRY 9
-#define OVERFLOW_FIGURE 0xffffffff
+#define OVERFLOW_FIGURE 0x100000000ULL
typedef struct _new_process
{
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;
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;
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 = 0;
char buf[BUFFER_SIZE];
- int i,j, k;
+ int i, k;
uint8_t cpu_id;
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;
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 */
+ }
+
+ if(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);
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;i<block_number;i++){
int event_count = 0;
- beat_count = 0;
memset((void*)buf_out, 0, block_size);
write_pos = buf_out;
write_pos_fac = buf_fac;
write_pos_proc = buf_proc;
- memset((void*)buffer,0,block_size);
- readFile(fd,(void*)buffer, block_size, "Unable to read block header");
+ memset((void*)buffer,0,ltt_block_size);
+ readFile(fd,(void*)buffer, ltt_block_size, "Unable to read block header");
cur_pos= buffer;
evId = *(uint8_t *)cur_pos;
startId = newId;
startTimeDelta = time_delta;
- previous_time_delta = time_delta;
start.seconds = tBufStart->Time.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));
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;
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:
close(fdProc);
fclose(fp);
+ g_printf("Conversion completed. Don't forget to copy core.xml to eventdefs directory\n");
+
+ return 0;
}