Fix: segfault on error handling
[babeltrace.git] / formats / ctf / ctf.c
index 65b4cf7643518b3b4362c8c314a0c43803bec837..ad218c0f3aeb5a5f50ca4c34bb5d1d0451a7f11f 100644 (file)
@@ -87,6 +87,12 @@ void ctf_set_handle(struct trace_descriptor *descriptor,
 
 static
 void ctf_close_trace(struct trace_descriptor *descriptor);
+static
+uint64_t ctf_timestamp_begin(struct trace_descriptor *descriptor,
+               struct bt_trace_handle *handle);
+static
+uint64_t ctf_timestamp_end(struct trace_descriptor *descriptor,
+               struct bt_trace_handle *handle);
 
 static
 rw_dispatch read_dispatch_table[] = {
@@ -119,8 +125,97 @@ struct format ctf_format = {
        .close_trace = ctf_close_trace,
        .set_context = ctf_set_context,
        .set_handle = ctf_set_handle,
+       .timestamp_begin = ctf_timestamp_begin,
+       .timestamp_end = ctf_timestamp_end,
 };
 
+static
+uint64_t ctf_timestamp_begin(struct trace_descriptor *descriptor,
+               struct bt_trace_handle *handle)
+{
+       struct ctf_trace *tin;
+       uint64_t begin = ULLONG_MAX;
+       int i, j;
+
+       tin = container_of(descriptor, struct ctf_trace, parent);
+
+       if (!tin)
+               goto error;
+
+       /* for each stream_class */
+       for (i = 0; i < tin->streams->len; i++) {
+               struct ctf_stream_declaration *stream_class;
+
+               stream_class = g_ptr_array_index(tin->streams, i);
+               /* for each file_stream */
+               for (j = 0; j < stream_class->streams->len; j++) {
+                       struct ctf_stream_definition *stream;
+                       struct ctf_file_stream *cfs;
+                       struct ctf_stream_pos *stream_pos;
+                       struct packet_index *index;
+
+                       stream = g_ptr_array_index(stream_class->streams, j);
+                       cfs = container_of(stream, struct ctf_file_stream,
+                                       parent);
+                       stream_pos = &cfs->pos;
+
+                       index = &g_array_index(stream_pos->packet_index,
+                                       struct packet_index, 0);
+                       if (index->timestamp_begin < begin)
+                               begin = index->timestamp_begin;
+               }
+       }
+
+       return begin;
+
+error:
+       return -1ULL;
+}
+
+static
+uint64_t ctf_timestamp_end(struct trace_descriptor *descriptor,
+               struct bt_trace_handle *handle)
+{
+       struct ctf_trace *tin;
+       uint64_t end = 0;
+       int i, j;
+
+       tin = container_of(descriptor, struct ctf_trace, parent);
+
+       if (!tin)
+               goto error;
+
+       /* for each stream_class */
+       for (i = 0; i < tin->streams->len; i++) {
+               struct ctf_stream_declaration *stream_class;
+
+               stream_class = g_ptr_array_index(tin->streams, i);
+               /* for each file_stream */
+               for (j = 0; j < stream_class->streams->len; j++) {
+                       struct ctf_stream_definition *stream;
+                       struct ctf_file_stream *cfs;
+                       struct ctf_stream_pos *stream_pos;
+                       struct packet_index *index;
+
+                       stream = g_ptr_array_index(stream_class->streams, j);
+                       cfs = container_of(stream, struct ctf_file_stream,
+                                       parent);
+                       stream_pos = &cfs->pos;
+
+                       index = &g_array_index(stream_pos->packet_index,
+                                       struct packet_index,
+                                       stream_pos->packet_index->len - 1);
+                       if (index->timestamp_end > end)
+                               end = index->timestamp_end;
+               }
+       }
+
+       return end;
+
+error:
+       return -1ULL;
+}
+
 /*
  * Update stream current timestamp, keep at clock frequency.
  */
@@ -888,7 +983,8 @@ end:
        ctf_scanner_free(scanner);
 end_scanner_alloc:
 end_packet_read:
-       fclose(fp);
+       if (fp)
+               fclose(fp);
        free(buf);
 end_stream:
        close(metadata_stream->pos.fd);
@@ -1617,6 +1713,28 @@ void ctf_close_trace(struct trace_descriptor *tdp)
                }
                g_ptr_array_free(td->streams, TRUE);
        }
+
+       if (td->event_declarations) {
+               for (i = 0; i < td->event_declarations->len; i++) {
+                       struct bt_ctf_event_decl *event;
+
+                       event = g_ptr_array_index(td->event_declarations, i);
+                       if (event->context_decl)
+                               g_ptr_array_free(event->context_decl, TRUE);
+                       if (event->fields_decl)
+                               g_ptr_array_free(event->fields_decl, TRUE);
+                       if (event->packet_header_decl)
+                               g_ptr_array_free(event->packet_header_decl, TRUE);
+                       if (event->event_context_decl)
+                               g_ptr_array_free(event->event_context_decl, TRUE);
+                       if (event->event_header_decl)
+                               g_ptr_array_free(event->event_header_decl, TRUE);
+                       if (event->packet_context_decl)
+                               g_ptr_array_free(event->packet_context_decl, TRUE);
+                       g_free(event);
+               }
+               g_ptr_array_free(td->event_declarations, TRUE);
+       }
        closedir(td->dir);
        g_free(td);
 }
This page took 0.024407 seconds and 4 git commands to generate.