add_one_trace may need to fetch new streams, which may lead to adding
new traces to the ctf_traces hashtable and recursively calling
add_one_trace. This is problematic because we cannot modify a hashtable
we are iterating on, and we cannot perform twice the add_one_trace for
the same trace.
This fix, ensures this situation cannot happen, by checking if the
number of traces changed during the iteration and by making sure a trace
is considered in_use as soon as we enter the add_one_trace function.
Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
Acked-by: Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
Tested-by: Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ /*
+ * add_one_trace can be called recursively if during the
+ * bt_context_add_trace call we need to fetch new streams, so we need to
+ * prevent a recursive call to process our current trace.
+ */
+ trace->in_use = 1;
BT_INIT_LIST_HEAD(&mmap_list.head);
BT_INIT_LIST_HEAD(&mmap_list.head);
printf_verbose("Trace now in use, id = %d\n", trace->trace_id);
goto end;
printf_verbose("Trace now in use, id = %d\n", trace->trace_id);
goto end;
GHashTableIter it;
gpointer key;
gpointer value;
GHashTableIter it;
gpointer key;
gpointer value;
+ unsigned int nr_traces;
printf_verbose("Begin add traces\n");
printf_verbose("Begin add traces\n");
+retry:
+ nr_traces = g_hash_table_size(ctx->session->ctf_traces);
+
ret = check_traces_metadata(ctx);
if (ret < 0) {
goto end;
ret = check_traces_metadata(ctx);
if (ret < 0) {
goto end;
if (ret < 0) {
goto end;
}
if (ret < 0) {
goto end;
}
+ /*
+ * If a new trace got added while we were adding the trace, the
+ * iterator is invalid and we have to restart.
+ */
+ if (g_hash_table_size(ctx->session->ctf_traces) != nr_traces) {
+ printf_verbose("New trace(s) added during add_one_trace()\n");
+ printf_verbose("JORAJ: GREP HERE\n");
+ goto retry;
+ }