From cb0a5cf8ba46a41be5a6d65ed8b9180e92196b75 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Fri, 9 Jun 2017 12:05:01 -0400 Subject: [PATCH] debug-info: sync the copied trace on static change MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Jérémie Galarneau --- plugins/libctfcopytrace/ctfcopytrace.c | 16 ++++ plugins/lttng-utils/copy.c | 125 ++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 11 deletions(-) diff --git a/plugins/libctfcopytrace/ctfcopytrace.c b/plugins/libctfcopytrace/ctfcopytrace.c index 54a7fd14..b8e28135 100644 --- a/plugins/libctfcopytrace/ctfcopytrace.c +++ b/plugins/libctfcopytrace/ctfcopytrace.c @@ -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__, diff --git a/plugins/lttng-utils/copy.c b/plugins/lttng-utils/copy.c index b71d8c9b..5acfe3f0 100644 --- a/plugins/lttng-utils/copy.c +++ b/plugins/lttng-utils/copy.c @@ -40,6 +40,12 @@ #include #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; -- 2.34.1