debug-info: sync the copied trace on static change
authorJulien Desfossez <jdesfossez@efficios.com>
Fri, 9 Jun 2017 16:05:01 +0000 (12:05 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 9 Jun 2017 21:03:27 +0000 (17:03 -0400)
When the trace becomes static, we need to ensure that we have all the
streams, stream classes and event classes in our own copy before setting
it static as well.

This is also true when we open the trace and it is already static.

Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
plugins/libctfcopytrace/ctfcopytrace.c
plugins/lttng-utils/copy.c

index 54a7fd14d175221989e01cf9ecabd0915d4a3f28..b8e281355b05abc44d798b8c337586719f28127e 100644 (file)
@@ -318,6 +318,22 @@ enum bt_component_status ctf_copy_event_classes(FILE *err,
                        ret = BT_COMPONENT_STATUS_ERROR;
                        goto error;
                }
+               if (i < bt_ctf_stream_class_get_event_class_count(writer_stream_class)) {
+                       writer_event_class = bt_ctf_stream_class_get_event_class_by_index(
+                                       writer_stream_class, i);
+                       if (writer_event_class) {
+                               /*
+                                * If the writer_event_class already exists,
+                                * just skip it. It can be used to resync the
+                                * event_classes after a trace has become
+                                * static.
+                                */
+                               BT_PUT(writer_event_class);
+                               BT_PUT(event_class);
+                               continue;
+                       }
+               }
+
                writer_event_class = ctf_copy_event_class(err, event_class);
                if (!writer_event_class) {
                        fprintf(err, "[error] %s in %s:%d\n", __func__,
index b71d8c9bb2fb6493d690f7f2cb88f1a09de67e23..5acfe3f0ae64acd4c8b2e1dfc55c81851135325a 100644 (file)
 #include <ctfcopytrace.h>
 #include "debug-info.h"
 
+static
+struct bt_ctf_stream *insert_new_stream(
+               struct debug_info_iterator *debug_it,
+               struct bt_ctf_stream *stream,
+               struct debug_info_trace *di_trace);
+
 static
 void unref_stream(struct bt_ctf_stream *stream)
 {
@@ -621,12 +627,89 @@ void debug_info_close_trace(struct debug_info_iterator *debug_it,
        g_hash_table_destroy(di_trace->trace_debug_map);
 }
 
+static
+int sync_event_classes(struct debug_info_iterator *debug_it,
+               struct bt_ctf_stream *stream,
+               struct bt_ctf_stream *writer_stream)
+{
+       int int_ret;
+       struct bt_ctf_stream_class *stream_class = NULL,
+                                  *writer_stream_class = NULL;
+       enum bt_component_status ret;
+
+       stream_class = bt_ctf_stream_get_class(stream);
+       if (!stream_class) {
+               fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto error;
+       }
+
+       writer_stream_class = bt_ctf_stream_get_class(writer_stream);
+       if (!writer_stream_class) {
+               fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto error;
+       }
+
+       ret = ctf_copy_event_classes(debug_it->err, stream_class,
+                       writer_stream_class);
+       if (ret != BT_COMPONENT_STATUS_OK) {
+               goto error;
+       }
+
+       int_ret = 0;
+       goto end;
+
+error:
+       int_ret = -1;
+end:
+       bt_put(stream_class);
+       bt_put(writer_stream_class);
+       return int_ret;
+}
+
 static
 void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
 {
        struct debug_info_trace *di_trace = data;
-       int trace_completed = 1;
+       struct debug_info_iterator *debug_it = di_trace->debug_it;
+       int trace_completed = 1, ret, nr_stream, i;
+       struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
+       struct bt_ctf_trace *writer_trace = di_trace->writer_trace;
 
+       /*
+        * When the trace becomes static, make sure that we have all
+        * the event classes in our stream_class copies before setting it
+        * static as well.
+        */
+       nr_stream = bt_ctf_trace_get_stream_count(trace);
+       for (i = 0; i < nr_stream; i++) {
+               stream = bt_ctf_trace_get_stream_by_index(trace, i);
+               if (!stream) {
+                       fprintf(debug_it->err,
+                                       "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto error;
+               }
+               writer_stream = bt_ctf_trace_get_stream_by_index(writer_trace, i);
+               if (!writer_stream) {
+                       fprintf(debug_it->err,
+                                       "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto error;
+               }
+               ret = sync_event_classes(di_trace->debug_it, stream, writer_stream);
+               if (ret) {
+                       fprintf(debug_it->err,
+                                       "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto error;
+               }
+               BT_PUT(stream);
+               BT_PUT(writer_stream);
+       }
+
+       bt_ctf_trace_set_is_static(di_trace->writer_trace);
        di_trace->trace_static = 1;
 
        g_hash_table_foreach(di_trace->stream_states,
@@ -636,6 +719,10 @@ void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
                g_hash_table_remove(di_trace->debug_it->trace_map,
                                di_trace->trace);
        }
+
+error:
+       bt_put(writer_stream);
+       bt_put(stream);
 }
 
 static
@@ -645,6 +732,7 @@ struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
        struct debug_info_trace *di_trace = NULL;
        struct bt_ctf_trace *trace = NULL;
        struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_stream *writer_stream = NULL;
        int ret, nr_stream, i;
 
        writer_trace = bt_ctf_trace_create();
@@ -696,6 +784,7 @@ struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
                        g_direct_equal, NULL, (GDestroyNotify) unref_debug_info);
        di_trace->stream_states = g_hash_table_new_full(g_direct_hash,
                        g_direct_equal, NULL, destroy_stream_state_key);
+       g_hash_table_insert(debug_it->trace_map, (gpointer) trace, di_trace);
 
        /* Set all the existing streams in the unknown state. */
        nr_stream = bt_ctf_trace_get_stream_count(trace);
@@ -708,6 +797,22 @@ struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
                        goto error;
                }
                insert_new_stream_state(debug_it, di_trace, stream);
+               writer_stream = insert_new_stream(debug_it, stream, di_trace);
+               if (!writer_stream) {
+                       fprintf(debug_it->err,
+                                       "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto error;
+               }
+               bt_get(writer_stream);
+               ret = sync_event_classes(debug_it, stream, writer_stream);
+               if (ret) {
+                       fprintf(debug_it->err,
+                                       "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto error;
+               }
+               BT_PUT(writer_stream);
                BT_PUT(stream);
        }
 
@@ -715,6 +820,7 @@ struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
        if (bt_ctf_trace_is_static(trace)) {
                di_trace->trace_static = 1;
                di_trace->static_listener_id = -1;
+               bt_ctf_trace_set_is_static(writer_trace);
        } else {
                ret = bt_ctf_trace_add_is_static_listener(trace,
                                trace_is_static_listener, di_trace);
@@ -727,7 +833,6 @@ struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
                di_trace->static_listener_id = ret;
        }
 
-       g_hash_table_insert(debug_it->trace_map, (gpointer) trace, di_trace);
 
        goto end;
 
@@ -736,6 +841,8 @@ error:
        g_free(di_trace);
        di_trace = NULL;
 end:
+       bt_put(stream);
+       bt_put(writer_stream);
        bt_put(stream_class);
        bt_put(trace);
        return di_trace;
@@ -1376,7 +1483,7 @@ struct bt_ctf_stream *debug_info_stream_begin(
                struct debug_info_iterator *debug_it,
                struct bt_ctf_stream *stream)
 {
-       struct bt_ctf_stream *writer_stream;
+       struct bt_ctf_stream *writer_stream = NULL;
        enum debug_info_stream_state *state;
        struct debug_info_trace *di_trace = NULL;
 
@@ -1390,13 +1497,6 @@ struct bt_ctf_stream *debug_info_stream_begin(
                }
        }
 
-       writer_stream = lookup_stream(debug_it, stream, di_trace);
-       if (writer_stream) {
-               fprintf(debug_it->err, "[error] %s in %s:%d\n",
-                               __func__, __FILE__, __LINE__);
-               goto error;
-       }
-
        /* Set the stream as active */
        state = g_hash_table_lookup(di_trace->stream_states, stream);
        if (!state) {
@@ -1415,7 +1515,10 @@ struct bt_ctf_stream *debug_info_stream_begin(
        }
        *state = DEBUG_INFO_ACTIVE_STREAM;
 
-       writer_stream = insert_new_stream(debug_it, stream, di_trace);
+       writer_stream = lookup_stream(debug_it, stream, di_trace);
+       if (!writer_stream) {
+               writer_stream = insert_new_stream(debug_it, stream, di_trace);
+       }
        bt_get(writer_stream);
 
        goto end;
This page took 0.02919 seconds and 4 git commands to generate.