X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fplugins%2Fctf%2Ffs-src%2Ffs.c;h=8036fe1598a10f5384f5a507718ce63af3c676e1;hb=bce64edbf55818ceb0113c5824e957af7c5f39ee;hp=1cb42e09791fd097715dce6c0aea71d482590b5f;hpb=1719bf6408b93c67c73b2d1d2c97db64cc8c7968;p=babeltrace.git diff --git a/src/plugins/ctf/fs-src/fs.c b/src/plugins/ctf/fs-src/fs.c index 1cb42e09..8036fe15 100644 --- a/src/plugins/ctf/fs-src/fs.c +++ b/src/plugins/ctf/fs-src/fs.c @@ -405,9 +405,8 @@ struct ctf_fs_component *ctf_fs_component_create(bt_logging_level log_level, goto end; error: - if (ctf_fs) { - ctf_fs_destroy(ctf_fs); - } + ctf_fs_destroy(ctf_fs); + ctf_fs = NULL; end: return ctf_fs; @@ -1770,6 +1769,15 @@ end: return ret; } +static +int decode_packet_first_event_timestamp(struct ctf_fs_trace *ctf_fs_trace, + struct ctf_clock_class *default_cc, + struct ctf_fs_ds_index_entry *index_entry, uint64_t *cs, int64_t *ts_ns) +{ + return decode_clock_snapshot_after_event(ctf_fs_trace, default_cc, + index_entry, FIRST_EVENT, cs, ts_ns); +} + static int decode_packet_last_event_timestamp(struct ctf_fs_trace *ctf_fs_trace, struct ctf_clock_class *default_cc, @@ -1869,6 +1877,167 @@ end: return ret; } +/* + * Fix up packet index entries for barectf's "event-before-packet" bug. + * Some buggy barectf tracer versions may emit events with a timestamp that is + * less than the timestamp_begin of the their packets. + * + * To fix up this erroneous data we do the following: + * 1. Starting at the second index entry, set the timestamp_begin of the + * current entry to the timestamp of the first event of the packet. + * 2. Set the previous entry's timestamp_end to the timestamp_begin of the + * current packet. + * + * Known buggy tracer versions: + * - before barectf 2.3.1 + */ +static +int fix_index_barectf_event_before_packet_bug(struct ctf_fs_trace *trace) +{ + int ret = 0; + guint ds_file_group_i; + GPtrArray *ds_file_groups = trace->ds_file_groups; + bt_logging_level log_level = trace->log_level; + + for (ds_file_group_i = 0; ds_file_group_i < ds_file_groups->len; + ds_file_group_i++) { + guint entry_i; + struct ctf_clock_class *default_cc; + struct ctf_fs_ds_file_group *ds_file_group = + g_ptr_array_index(ds_file_groups, ds_file_group_i); + + struct ctf_fs_ds_index *index = ds_file_group->index; + + BT_ASSERT(index); + BT_ASSERT(index->entries); + BT_ASSERT(index->entries->len > 0); + + BT_ASSERT(ds_file_group->sc->default_clock_class); + default_cc = ds_file_group->sc->default_clock_class; + + /* + * 1. Iterate over the index, starting from the second entry + * (index = 1). + */ + for (entry_i = 1; entry_i < index->entries->len; + entry_i++) { + struct ctf_fs_ds_index_entry *curr_entry, *prev_entry; + prev_entry = g_ptr_array_index(index->entries, entry_i - 1); + curr_entry = g_ptr_array_index(index->entries, entry_i); + /* + * 2. Set the current entry `begin` timestamp to the + * timestamp of the first event of the current packet. + */ + ret = decode_packet_first_event_timestamp(trace, default_cc, + curr_entry, &curr_entry->timestamp_begin, + &curr_entry->timestamp_begin_ns); + if (ret) { + BT_LOGE_STR("Failed to decode first event's clock snapshot"); + goto end; + } + + /* + * 3. Set the previous entry `end` timestamp to the + * timestamp of the first event of the current packet. + */ + prev_entry->timestamp_end = curr_entry->timestamp_begin; + prev_entry->timestamp_end_ns = curr_entry->timestamp_begin_ns; + } + } +end: + return ret; +} + +/* + * When using the lttng-crash feature it's likely that the last packets of each + * stream have their timestamp_end set to zero. This is caused by the fact that + * the tracer crashed and was not able to properly close the packets. + * + * To fix up this erroneous data we do the following: + * For each index entry, if the entry's timestamp_end is 0 and the + * timestamp_begin is not 0: + * - If it's the stream file's last packet: set the packet index entry's end + * time to the packet's last event's time, if any, or to the packet's + * beginning time otherwise. + * - If it's not the stream file's last packet: set the packet index + * entry's end time to the next packet's beginning time. + * + * Affected versions: + * - All current and future lttng-ust and lttng-modules versions. + */ +static +int fix_index_lttng_crash_quirk(struct ctf_fs_trace *trace) +{ + int ret = 0; + guint ds_file_group_idx; + GPtrArray *ds_file_groups = trace->ds_file_groups; + bt_logging_level log_level = trace->log_level; + + for (ds_file_group_idx = 0; ds_file_group_idx < ds_file_groups->len; + ds_file_group_idx++) { + guint entry_idx; + struct ctf_clock_class *default_cc; + struct ctf_fs_ds_index_entry *last_entry; + struct ctf_fs_ds_index *index; + + struct ctf_fs_ds_file_group *ds_file_group = + g_ptr_array_index(ds_file_groups, ds_file_group_idx); + + BT_ASSERT(ds_file_group); + index = ds_file_group->index; + + BT_ASSERT(ds_file_group->sc->default_clock_class); + default_cc = ds_file_group->sc->default_clock_class; + + BT_ASSERT(index); + BT_ASSERT(index->entries); + BT_ASSERT(index->entries->len > 0); + + last_entry = g_ptr_array_index(index->entries, + index->entries->len - 1); + BT_ASSERT(last_entry); + + + /* 1. Fix the last entry first. */ + if (last_entry->timestamp_end == 0 && + last_entry->timestamp_begin != 0) { + /* + * Decode packet to read the timestamp of the + * last event of the stream file. + */ + ret = decode_packet_last_event_timestamp(trace, + default_cc, last_entry, + &last_entry->timestamp_end, + &last_entry->timestamp_end_ns); + if (ret) { + BT_LOGE_STR("Failed to decode last event's clock snapshot"); + goto end; + } + } + + /* Iterate over all entries but the last one. */ + for (entry_idx = 0; entry_idx < index->entries->len - 1; + entry_idx++) { + struct ctf_fs_ds_index_entry *curr_entry, *next_entry; + curr_entry = g_ptr_array_index(index->entries, entry_idx); + next_entry = g_ptr_array_index(index->entries, entry_idx + 1); + + if (curr_entry->timestamp_end == 0 && + curr_entry->timestamp_begin != 0) { + /* + * 2. Set the current index entry `end` timestamp to + * the next index entry `begin` timestamp. + */ + curr_entry->timestamp_end = next_entry->timestamp_begin; + curr_entry->timestamp_end_ns = next_entry->timestamp_begin_ns; + } + } + } + +end: + return ret; +} + /* * Extract the tracer information necessary to compare versions. * Returns 0 on success, and -1 if the extraction is not successful because the @@ -1982,6 +2151,46 @@ bool is_tracer_affected_by_lttng_event_after_packet_bug( return is_affected; } +static +bool is_tracer_affected_by_barectf_event_before_packet_bug( + struct tracer_info *curr_tracer_info) +{ + bool is_affected = false; + + if (strcmp(curr_tracer_info->name, "barectf") == 0) { + if (curr_tracer_info->major < 2) { + is_affected = true; + } else if (curr_tracer_info->major == 2) { + if (curr_tracer_info->minor < 3) { + is_affected = true; + } else if (curr_tracer_info->minor == 3) { + /* fixed in barectf 2.3.1 */ + if (curr_tracer_info->patch < 1) { + is_affected = true; + } + } + } + } + + return is_affected; +} + +static +bool is_tracer_affected_by_lttng_crash_quirk( + struct tracer_info *curr_tracer_info) +{ + bool is_affected = false; + + /* All LTTng tracer may be affected by this lttng crash quirk. */ + if (strcmp(curr_tracer_info->name, "lttng-ust") == 0) { + is_affected = true; + } else if (strcmp(curr_tracer_info->name, "lttng-modules") == 0) { + is_affected = true; + } + + return is_affected; +} + /* * Looks for trace produced by known buggy tracers and fix up the index * produced earlier. @@ -2026,6 +2235,28 @@ int fix_packet_index_tracer_bugs(struct ctf_fs_component *ctf_fs) BT_LOGE_STR("Failed to fix LTTng event-after-packet bug."); goto end; } + trace->metadata->tc->quirks.lttng_event_after_packet = true; + } + + if (is_tracer_affected_by_barectf_event_before_packet_bug( + ¤t_tracer_info)) { + BT_LOGI_STR("Trace may be affected by barectf tracer packet timestamp bug. Fixing up."); + ret = fix_index_barectf_event_before_packet_bug(trace); + if (ret) { + BT_LOGE_STR("Failed to fix barectf event-before-packet bug."); + goto end; + } + trace->metadata->tc->quirks.barectf_event_before_packet = true; + } + + if (is_tracer_affected_by_lttng_crash_quirk( + ¤t_tracer_info)) { + ret = fix_index_lttng_crash_quirk(trace); + if (ret) { + BT_LOGE_STR("Failed to fix lttng-crash timestamp quirks."); + goto end; + } + trace->metadata->tc->quirks.lttng_crash = true; } } end: