X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Fltt%2Ftracefile.c;h=a1e19a7fae56871a6d0889a6101c35ce8f760780;hb=9d7e0c255f8df252a67f60bbb3ddd8c6b4dde0d9;hp=5ddabdbd0adebe857d717cad29f202c400b5e4ee;hpb=5a69756597a55db56efb61388060c535854f44e2;p=lttv.git diff --git a/ltt/branches/poly/ltt/tracefile.c b/ltt/branches/poly/ltt/tracefile.c index 5ddabdbd..a1e19a7f 100644 --- a/ltt/branches/poly/ltt/tracefile.c +++ b/ltt/branches/poly/ltt/tracefile.c @@ -3,19 +3,19 @@ * * Complete rewrite from the original version made by XangXiu Yang. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License Version 2.1 as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H @@ -106,7 +106,7 @@ static int ltt_seek_next_event(LttTracefile *tf); void ltt_update_event_size(LttTracefile *tf); -void precompute_offsets(LttTracefile *tf, LttEventType *event); +void precompute_offsets(LttFacility *fac, LttEventType *event); #if 0 /* Functions to parse system.xml file (using glib xml parser) */ @@ -232,7 +232,7 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t) t->ltt_minor_version = any->minor_version; t->flight_recorder = any->flight_recorder; t->has_heartbeat = any->has_heartbeat; - t->has_tsc = any->has_tsc; + t->freq_scale = any->freq_scale; } @@ -250,13 +250,13 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t) return 1; } break; - case 6: + case 7: { - struct ltt_trace_header_0_6 *vheader = - (struct ltt_trace_header_0_6 *)header; + struct ltt_trace_header_0_7 *vheader = + (struct ltt_trace_header_0_7 *)header; tf->buffer_header_size = sizeof(struct ltt_block_start_header) - + sizeof(struct ltt_trace_header_0_6); + + sizeof(struct ltt_trace_header_0_7); if(t) { t->start_freq = ltt_get_uint64(LTT_GET_BO(tf), &vheader->start_freq); @@ -858,6 +858,8 @@ static int ltt_get_facility_description(LttFacility *f, const gchar *text; guint textlen; gint err; + gint arch_spec; + gint fac_name_len; text = g_quark_to_string(t->pathname); textlen = strlen(text); @@ -871,9 +873,21 @@ static int ltt_get_facility_description(LttFacility *f, strcat(desc_file_name, text); text = g_quark_to_string(f->name); - textlen+=strlen(text); + fac_name_len = strlen(text); + textlen+=fac_name_len; if(textlen >= PATH_MAX) goto name_error; strcat(desc_file_name, text); + + /* arch specific facilities are named like this : name_arch */ + if(fac_name_len+1 < sizeof("_arch")) + arch_spec = 0; + else { + if(!strcmp(&text[fac_name_len+1-sizeof("_arch")], "_arch")) + arch_spec = 1; + else + arch_spec = 0; + } + #if 0 text = "_"; textlen+=strlen(text); @@ -887,6 +901,41 @@ static int ltt_get_facility_description(LttFacility *f, textlen=strlen(desc_file_name); #endif //0 + + if(arch_spec) { + switch(t->arch_type) { + case LTT_ARCH_TYPE_I386: + text = "_i386"; + break; + case LTT_ARCH_TYPE_PPC: + text = "_ppc"; + break; + case LTT_ARCH_TYPE_SH: + text = "_sh"; + break; + case LTT_ARCH_TYPE_S390: + text = "_s390"; + break; + case LTT_ARCH_TYPE_MIPS: + text = "_mips"; + break; + case LTT_ARCH_TYPE_ARM: + text = "_arm"; + break; + case LTT_ARCH_TYPE_PPC64: + text = "_ppc64"; + break; + case LTT_ARCH_TYPE_X86_64: + text = "_x86_64"; + break; + default: + g_error("Trace from unsupported architecture."); + } + textlen+=strlen(text); + if(textlen >= PATH_MAX) goto name_error; + strcat(desc_file_name, text); + } + text = ".xml"; textlen+=strlen(text); if(textlen >= PATH_MAX) goto name_error; @@ -951,6 +1000,7 @@ static int ltt_process_facility_tracefile(LttTracefile *tf) struct LttFacilityLoad *fac_load_data; struct LttStateDumpFacilityLoad *fac_state_dump_load_data; char *fac_name; + void *pos; // FIXME align switch((enum ltt_core_events)tf->event.event_id) { @@ -958,9 +1008,10 @@ static int ltt_process_facility_tracefile(LttTracefile *tf) fac_name = (char*)(tf->event.data); g_debug("Doing LTT_EVENT_FACILITY_LOAD of facility %s", fac_name); - fac_load_data = - (struct LttFacilityLoad *) - (tf->event.data + strlen(fac_name) + 1); + pos = (tf->event.data + strlen(fac_name) + 1); + pos += ltt_align((size_t)pos, sizeof(guint32), tf->has_alignment); + fac_load_data = (struct LttFacilityLoad *)pos; + fac = &g_array_index (tf->trace->facilities_by_num, LttFacility, ltt_get_uint32(LTT_GET_BO(tf), &fac_load_data->id)); /* facility may already exist if trace is paused/unpaused */ @@ -988,7 +1039,7 @@ static int ltt_process_facility_tracefile(LttTracefile *tf) /* Preset the field offsets */ for(i=0; ievents->len; i++){ et = &g_array_index(fac->events, LttEventType, i); - precompute_offsets(tf, et); + precompute_offsets(fac, et); } fac->exists = 1; @@ -1013,9 +1064,10 @@ static int ltt_process_facility_tracefile(LttTracefile *tf) fac_name = (char*)(tf->event.data); g_debug("Doing LTT_EVENT_STATE_DUMP_FACILITY_LOAD of facility %s", fac_name); - fac_state_dump_load_data = - (struct LttStateDumpFacilityLoad *) - (tf->event.data + strlen(fac_name) + 1); + pos = (tf->event.data + strlen(fac_name) + 1); + pos += ltt_align((size_t)pos, sizeof(guint32), tf->has_alignment); + fac_state_dump_load_data = (struct LttStateDumpFacilityLoad *)pos; + fac = &g_array_index (tf->trace->facilities_by_num, LttFacility, ltt_get_uint32(LTT_GET_BO(tf), &fac_state_dump_load_data->id)); /* facility may already exist if trace is paused/unpaused */ @@ -1043,7 +1095,7 @@ static int ltt_process_facility_tracefile(LttTracefile *tf) /* Preset the field offsets */ for(i=0; ievents->len; i++){ et = &g_array_index(fac->events, LttEventType, i); - precompute_offsets(tf, et); + precompute_offsets(fac, et); } fac->exists = 1; @@ -1530,6 +1582,10 @@ int ltt_tracefile_seek_position(LttTracefile *tf, const LttEventPosition *ep) { tf->event.offset = ep->offset; + /* Put back the event real tsc */ + tf->event.tsc = ep->tsc; + tf->buffer.tsc = ep->tsc; + err = ltt_tracefile_read_update_event(tf); if(err) goto fail; err = ltt_tracefile_read_op(tf); @@ -1548,12 +1604,11 @@ LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event) { LttTime time; - g_assert(tf->trace->has_tsc); - // time = ltt_time_from_uint64( // cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count))); time = ltt_time_from_uint64( - (double)(tf->buffer.tsc - tf->trace->start_tsc) * 1000000.0 + (double)(tf->buffer.tsc - tf->trace->start_tsc) + * (1000000000.0 / tf->trace->freq_scale) / (double)tf->trace->start_freq); //time = ltt_time_add(tf->buffer.begin.timestamp, time); time = ltt_time_add(tf->trace->start_time_from_tsc, time); @@ -1669,43 +1724,29 @@ int ltt_tracefile_read_update_event(LttTracefile *tf) /* Align the head */ pos += ltt_align((size_t)pos, tf->trace->arch_size, tf->has_alignment); - if(tf->trace->has_tsc) { - if(tf->trace->has_heartbeat) { - event->time.timestamp = ltt_get_uint32(LTT_GET_BO(tf), - pos); - /* 32 bits -> 64 bits tsc */ - /* note : still works for seek and non seek cases. */ - if(event->time.timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) { - tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL) - + 0x100000000ULL) - | (guint64)event->time.timestamp; - event->tsc = tf->buffer.tsc; - } else { - /* no overflow */ - tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) - | (guint64)event->time.timestamp; - event->tsc = tf->buffer.tsc; - } - pos += sizeof(guint32); - } else { - event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos); - tf->buffer.tsc = event->tsc; - pos += sizeof(guint64); - } - - event->event_time = ltt_interpolate_time(tf, event); - } else { - event->time.delta.tv_sec = 0; - event->time.delta.tv_nsec = ltt_get_uint32(LTT_GET_BO(tf), - pos) * NSEC_PER_USEC; - tf->buffer.tsc = 0; - event->tsc = tf->buffer.tsc; - - event->event_time = ltt_time_add(tf->buffer.begin.timestamp, - event->time.delta); - pos += sizeof(guint32); - } - + if(tf->trace->has_heartbeat) { + event->timestamp = ltt_get_uint32(LTT_GET_BO(tf), + pos); + /* 32 bits -> 64 bits tsc */ + /* note : still works for seek and non seek cases. */ + if(event->timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) { + tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL) + + 0x100000000ULL) + | (guint64)event->timestamp; + event->tsc = tf->buffer.tsc; + } else { + /* no overflow */ + tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) + | (guint64)event->timestamp; + event->tsc = tf->buffer.tsc; + } + pos += sizeof(guint32); + } else { + event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos); + tf->buffer.tsc = event->tsc; + pos += sizeof(guint64); + } + event->event_time = ltt_interpolate_time(tf, event); event->facility_id = *(guint8*)pos; pos += sizeof(guint8); @@ -1863,6 +1904,7 @@ void ltt_update_event_size(LttTracefile *tf) case LTT_EVENT_FACILITY_LOAD: size = strlen((char*)tf->event.data) + 1; //g_debug("Update Event facility load of facility %s", (char*)tf->event.data); + size += ltt_align(size, sizeof(guint32), tf->has_alignment); size += sizeof(struct LttFacilityLoad); break; case LTT_EVENT_FACILITY_UNLOAD: @@ -1871,6 +1913,7 @@ void ltt_update_event_size(LttTracefile *tf) break; case LTT_EVENT_STATE_DUMP_FACILITY_LOAD: size = strlen((char*)tf->event.data) + 1; + size += ltt_align(size, sizeof(guint32), tf->has_alignment); //g_debug("Update Event facility load state dump of facility %s", // (char*)tf->event.data); size += sizeof(struct LttStateDumpFacilityLoad); @@ -1889,7 +1932,7 @@ void ltt_update_event_size(LttTracefile *tf) } } else { if(!f->exists) { - g_error("Unknown facility %hhu (0x%hhx) in tracefile %s", + g_warning("Unknown facility %hhu (0x%hhx) in tracefile %s", tf->event.facility_id, tf->event.facility_id, g_quark_to_string(tf->name)); @@ -1900,7 +1943,7 @@ void ltt_update_event_size(LttTracefile *tf) ltt_facility_eventtype_get(f, tf->event.event_id); if(!event_type) { - g_error("Unknown event id %hhu in facility %s in tracefile %s", + g_warning("Unknown event id %hhu in facility %s in tracefile %s", tf->event.event_id, g_quark_to_string(f->name), g_quark_to_string(tf->name)); @@ -1908,7 +1951,7 @@ void ltt_update_event_size(LttTracefile *tf) } /* Compute the dynamic offsets */ - compute_offsets(tf, event_type, &size, tf->event.data); + compute_offsets(tf, f, event_type, &size, tf->event.data); //g_debug("Event root field : f.e %hhu.%hhu size %zd", // tf->event.facility_id, @@ -1918,6 +1961,10 @@ void ltt_update_event_size(LttTracefile *tf) tf->event.data_size = size; /* Check consistency between kernel and LTTV structure sizes */ + if(tf->event.event_size == 0xFFFF) { + /* Event size too big to fit in the event size field */ + tf->event.event_size = tf->event.data_size; + } g_assert(tf->event.data_size == tf->event.event_size); return; @@ -1925,7 +1972,12 @@ void ltt_update_event_size(LttTracefile *tf) facility_error: event_type_error: event_id_error: - tf->event.data_size = 0; + if(tf->event.event_size == 0xFFFF) { + g_error("Cannot jump over an unknown event bigger than 0xFFFE bytes"); + } + /* The facility is unknown : use the kernel information about this event + * to jump over it. */ + tf->event.data_size = tf->event.event_size; } @@ -2044,13 +2096,12 @@ void set_fields_offsets(LttTracefile *tf, LttEventType *event_type) *Function name * get_alignment : Get the alignment needed for a field. *Input params - * tf : tracefile * field : field * * returns : The size on which it must be aligned. * ****************************************************************************/ -off_t get_alignment(LttTracefile *tf, LttField *field) +off_t get_alignment(LttField *field) { LttType *type = &field->field_type; @@ -2081,7 +2132,7 @@ off_t get_alignment(LttTracefile *tf, LttField *field) g_assert(type->fields->len == 1); { LttField *child = &g_array_index(type->fields, LttField, 0); - return get_alignment(tf, child); + return get_alignment(child); } break; case LTT_SEQUENCE: @@ -2090,10 +2141,10 @@ off_t get_alignment(LttTracefile *tf, LttField *field) off_t localign = 0; LttField *child = &g_array_index(type->fields, LttField, 0); - localign = max(localign, get_alignment(tf, child)); + localign = max(localign, get_alignment(child)); child = &g_array_index(type->fields, LttField, 1); - localign = max(localign, get_alignment(tf, child)); + localign = max(localign, get_alignment(child)); return localign; } @@ -2106,7 +2157,7 @@ off_t get_alignment(LttTracefile *tf, LttField *field) for(i=0; ifields->len; i++) { LttField *child = &g_array_index(type->fields, LttField, i); - localign = max(localign, get_alignment(tf, child)); + localign = max(localign, get_alignment(child)); } return localign; } @@ -2129,7 +2180,7 @@ off_t get_alignment(LttTracefile *tf, LttField *field) * ****************************************************************************/ -void field_compute_static_size(LttTracefile *tf, LttField *field) +void field_compute_static_size(LttFacility *fac, LttField *field) { LttType *type = &field->field_type; @@ -2159,7 +2210,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field) g_assert(type->fields->len == 1); { LttField *child = &g_array_index(type->fields, LttField, 0); - field_compute_static_size(tf, child); + field_compute_static_size(fac, child); if(child->field_size != 0) { field->field_size = type->size * child->field_size; @@ -2175,7 +2226,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field) { off_t local_offset = 0; LttField *child = &g_array_index(type->fields, LttField, 1); - field_compute_static_size(tf, child); + field_compute_static_size(fac, child); field->field_size = 0; type->size = 0; if(child->field_size != 0) { @@ -2190,10 +2241,10 @@ void field_compute_static_size(LttTracefile *tf, LttField *field) guint i; for(i=0;ifields->len;i++) { LttField *child = &g_array_index(type->fields, LttField, i); - field_compute_static_size(tf, child); + field_compute_static_size(fac, child); if(child->field_size != 0) { - type->size += ltt_align(type->size, get_alignment(tf, child), - tf->has_alignment); + type->size += ltt_align(type->size, get_alignment(child), + fac->alignment); type->size += child->field_size; } else { /* As soon as we find a child with variable size, we have @@ -2217,7 +2268,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field) *Function name * precompute_fields_offsets : set the precomputable offset of the fields *Input params - * tf : tracefile + * fac : facility * field : the field * offset : pointer to the current offset, must be incremented * @@ -2226,7 +2277,7 @@ void field_compute_static_size(LttTracefile *tf, LttField *field) ****************************************************************************/ -gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) +gint precompute_fields_offsets(LttFacility *fac, LttField *field, off_t *offset) { LttType *type = &field->field_type; @@ -2247,9 +2298,10 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) case LTT_OFF_T: case LTT_FLOAT: case LTT_ENUM: + g_assert(field->field_size != 0); /* Align offset on type size */ - *offset += ltt_align(*offset, get_alignment(tf, field), - tf->has_alignment); + *offset += ltt_align(*offset, get_alignment(field), + fac->alignment); /* remember offset */ field->offset_root = *offset; field->fixed_root = FIELD_FIXED; @@ -2267,8 +2319,8 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) { LttField *child = &g_array_index(type->fields, LttField, 0); - *offset += ltt_align(*offset, get_alignment(tf, field), - tf->has_alignment); + *offset += ltt_align(*offset, get_alignment(field), + fac->alignment); /* remember offset */ field->offset_root = *offset; @@ -2294,23 +2346,23 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) LttField *child; guint ret; - *offset += ltt_align(*offset, get_alignment(tf, field), - tf->has_alignment); + *offset += ltt_align(*offset, get_alignment(field), + fac->alignment); /* remember offset */ field->offset_root = *offset; field->fixed_root = FIELD_FIXED; child = &g_array_index(type->fields, LttField, 0); - ret = precompute_fields_offsets(tf, child, offset); + ret = precompute_fields_offsets(fac, child, offset); g_assert(ret == 0); /* Seq len cannot have variable len */ child = &g_array_index(type->fields, LttField, 1); - *offset += ltt_align(*offset, get_alignment(tf, child), - tf->has_alignment); + *offset += ltt_align(*offset, get_alignment(child), + fac->alignment); field->array_offset = *offset; - /* Set the offset position at position 0 */ - ret = precompute_fields_offsets(tf, child, offset); + /* Let the child be variable. */ + //ret = precompute_fields_offsets(fac, child, offset); /* Cannot precompute fields offsets of sequence members, and has * variable length. */ @@ -2323,15 +2375,15 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) guint i; gint ret=0; - *offset += ltt_align(*offset, get_alignment(tf, field), - tf->has_alignment); + *offset += ltt_align(*offset, get_alignment(field), + fac->alignment); /* remember offset */ field->offset_root = *offset; field->fixed_root = FIELD_FIXED; for(i=0; i< type->fields->len; i++) { child = &g_array_index(type->fields, LttField, i); - ret = precompute_fields_offsets(tf, child, offset); + ret = precompute_fields_offsets(fac, child, offset); if(ret) break; } @@ -2344,8 +2396,8 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) guint i; gint ret=0; - *offset += ltt_align(*offset, get_alignment(tf, field), - tf->has_alignment); + *offset += ltt_align(*offset, get_alignment(field), + fac->alignment); /* remember offset */ field->offset_root = *offset; field->fixed_root = FIELD_FIXED; @@ -2353,7 +2405,7 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) for(i=0; i< type->fields->len; i++) { *offset = field->offset_root; child = &g_array_index(type->fields, LttField, i); - ret = precompute_fields_offsets(tf, child, offset); + ret = precompute_fields_offsets(fac, child, offset); if(ret) break; } @@ -2379,7 +2431,7 @@ gint precompute_fields_offsets(LttTracefile *tf, LttField *field, off_t *offset) * event : event type * ****************************************************************************/ -void precompute_offsets(LttTracefile *tf, LttEventType *event) +void precompute_offsets(LttFacility *fac, LttEventType *event) { guint i; off_t offset = 0; @@ -2389,13 +2441,13 @@ void precompute_offsets(LttTracefile *tf, LttEventType *event) * arrays, struct and unions, which is not done by the parser */ for(i=0; ifields->len; i++) { LttField *field = &g_array_index(event->fields, LttField, i); - field_compute_static_size(tf, field); + field_compute_static_size(fac, field); } /* Precompute all known offsets */ for(i=0; ifields->len; i++) { LttField *field = &g_array_index(event->fields, LttField, i); - ret = precompute_fields_offsets(tf, field, &offset); + ret = precompute_fields_offsets(fac, field, &offset); if(ret) break; } } @@ -2614,6 +2666,10 @@ gint check_fields_compatibility(LttEventType *event_type1, different = 1; goto end; } + if(type1->network != type2->network) { + different = 1; + goto end; + } switch(type1->type_class) { case LTT_INT_FIXED: