+
+static
+void update_event_statedump_if_needed(struct debug_info_msg_iter *debug_it,
+ const bt_event *in_event)
+{
+ const bt_field *event_common_ctx;
+ const bt_field_class *event_common_ctx_fc;
+ const bt_event_class *in_event_class = bt_event_borrow_class_const(in_event);
+
+ /*
+ * If the event is an lttng_ust_statedump event AND has the right event
+ * common context fields update the debug-info view for this process.
+ */
+ event_common_ctx = bt_event_borrow_common_context_field_const(in_event);
+ if (!event_common_ctx) {
+ goto end;
+ }
+
+ event_common_ctx_fc = bt_field_borrow_class_const(event_common_ctx);
+ if (is_event_common_ctx_dbg_info_compatible(event_common_ctx_fc,
+ debug_it->ir_maps->debug_info_field_class_name)) {
+ /* Checkout if it might be a one of lttng ust statedump events. */
+ const char *in_event_name = bt_event_class_get_name(in_event_class);
+ if (strncmp(in_event_name, LTTNG_UST_STATEDUMP_PREFIX,
+ strlen(LTTNG_UST_STATEDUMP_PREFIX)) == 0) {
+ /* Handle statedump events. */
+ handle_event_statedump(debug_it, in_event);
+ }
+ }
+end:
+ return;
+}
+
+static
+bt_message *handle_event_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_clock_snapshot *cs;
+ const bt_clock_class *default_cc;
+ const bt_packet *in_packet;
+ bt_clock_snapshot_state cs_state;
+ bt_event_class *out_event_class;
+ bt_packet *out_packet;
+ bt_event *out_event;
+
+ bt_message *out_message = NULL;
+
+ /* Borrow the input event and its event class. */
+ const bt_event *in_event =
+ bt_message_event_borrow_event_const(in_message);
+ const bt_event_class *in_event_class =
+ bt_event_borrow_class_const(in_event);
+
+ update_event_statedump_if_needed(debug_it, in_event);
+
+ out_event_class = trace_ir_mapping_borrow_mapped_event_class(
+ debug_it->ir_maps, in_event_class);
+ if (!out_event_class) {
+ out_event_class = trace_ir_mapping_create_new_mapped_event_class(
+ debug_it->ir_maps, in_event_class);
+ }
+ BT_ASSERT(out_event_class);
+
+ /* Borrow the input and output packets. */
+ in_packet = bt_event_borrow_packet_const(in_event);
+ out_packet = trace_ir_mapping_borrow_mapped_packet(debug_it->ir_maps,
+ in_packet);
+
+ default_cc = bt_stream_class_borrow_default_clock_class_const(
+ bt_event_class_borrow_stream_class_const(in_event_class));
+ if (default_cc) {
+ /* Borrow event clock snapshot. */
+ cs_state =
+ bt_message_event_borrow_default_clock_snapshot_const(
+ in_message, &cs);
+
+ /* Create an output event message. */
+ BT_ASSERT (cs_state == BT_CLOCK_SNAPSHOT_STATE_KNOWN);
+ out_message = bt_message_event_create_with_default_clock_snapshot(
+ debug_it->input_iterator,
+ out_event_class, out_packet,
+ bt_clock_snapshot_get_value(cs));
+ } else {
+ out_message = bt_message_event_create(debug_it->input_iterator,
+ out_event_class, out_packet);
+ }
+
+ if (!out_message) {
+ BT_LOGE("Error creating output event message.");
+ goto error;
+ }
+
+ out_event = bt_message_event_borrow_event(out_message);
+
+ /* Copy the original fields to the output event. */
+ copy_event_content(in_event, out_event);
+
+ /*
+ * Try to set the debug-info fields based on debug information that is
+ * gathered so far.
+ */
+ fill_debug_info_event_if_needed(debug_it, in_event, out_event);
+
+error:
+ return out_message;
+}
+
+static
+bt_message *handle_stream_begin_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_stream *in_stream;
+ bt_message *out_message;
+ bt_stream *out_stream;
+
+ in_stream = bt_message_stream_beginning_borrow_stream_const(in_message);
+ BT_ASSERT(in_stream);
+
+ /* Create a duplicated output stream. */
+ out_stream = trace_ir_mapping_create_new_mapped_stream(
+ debug_it->ir_maps, in_stream);
+ if (!out_stream) {
+ out_message = NULL;
+ goto error;
+ }
+
+ /* Create an output stream beginning message. */
+ out_message = bt_message_stream_beginning_create(
+ debug_it->input_iterator, out_stream);
+ if (!out_message) {
+ BT_LOGE("Error creating output stream beginning message: "
+ "out-s-addr=%p", out_stream);
+ }
+error:
+ return out_message;
+}
+
+static
+bt_message *handle_stream_end_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_stream *in_stream;
+ bt_message *out_message = NULL;
+ bt_stream *out_stream;
+
+ in_stream = bt_message_stream_end_borrow_stream_const(in_message);
+ BT_ASSERT(in_stream);
+
+ out_stream = trace_ir_mapping_borrow_mapped_stream(
+ debug_it->ir_maps, in_stream);
+ BT_ASSERT(out_stream);
+
+ /* Create an output stream end message. */
+ out_message = bt_message_stream_end_create(debug_it->input_iterator,
+ out_stream);
+ if (!out_message) {
+ BT_LOGE("Error creating output stream end message: out-s-addr=%p",
+ out_stream);
+ }
+
+ /* Remove stream from trace mapping hashtable. */
+ trace_ir_mapping_remove_mapped_stream(debug_it->ir_maps, in_stream);
+
+ return out_message;
+}
+
+static
+bt_message *handle_packet_begin_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_clock_class *default_cc;
+ bt_clock_snapshot_state cs_state;
+ const bt_clock_snapshot *cs;
+ bt_message *out_message = NULL;
+ bt_packet *out_packet;
+
+ const bt_packet *in_packet =
+ bt_message_packet_beginning_borrow_packet_const(in_message);
+ BT_ASSERT(in_packet);
+
+ /* This packet should not be already mapped. */
+ BT_ASSERT(!trace_ir_mapping_borrow_mapped_packet(
+ debug_it->ir_maps, in_packet));
+
+ out_packet = trace_ir_mapping_create_new_mapped_packet(debug_it->ir_maps,
+ in_packet);
+
+ BT_ASSERT(out_packet);
+
+ default_cc = bt_stream_class_borrow_default_clock_class_const(
+ bt_stream_borrow_class_const(
+ bt_packet_borrow_stream_const(in_packet)));
+ if (default_cc) {
+ /* Borrow clock snapshot. */
+ cs_state =
+ bt_message_packet_beginning_borrow_default_clock_snapshot_const(
+ in_message, &cs);
+
+ /* Create an output packet beginning message. */
+ BT_ASSERT(cs_state == BT_CLOCK_SNAPSHOT_STATE_KNOWN);
+ out_message = bt_message_packet_beginning_create_with_default_clock_snapshot(
+ debug_it->input_iterator, out_packet,
+ bt_clock_snapshot_get_value(cs));
+ } else {
+ out_message = bt_message_packet_beginning_create(
+ debug_it->input_iterator, out_packet);
+ }
+ if (!out_message) {
+ BT_LOGE("Error creating output packet beginning message: "
+ "out-p-addr=%p", out_packet);
+ }
+
+ return out_message;
+}
+
+static
+bt_message *handle_packet_end_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_clock_snapshot *cs;
+ const bt_packet *in_packet;
+ const bt_clock_class *default_cc;
+ bt_clock_snapshot_state cs_state;
+ bt_message *out_message = NULL;
+ bt_packet *out_packet;
+
+ in_packet = bt_message_packet_end_borrow_packet_const(in_message);
+ BT_ASSERT(in_packet);
+
+ out_packet = trace_ir_mapping_borrow_mapped_packet(debug_it->ir_maps, in_packet);
+ BT_ASSERT(out_packet);
+
+ default_cc = bt_stream_class_borrow_default_clock_class_const(
+ bt_stream_borrow_class_const(
+ bt_packet_borrow_stream_const(in_packet)));
+ if (default_cc) {
+ /* Borrow clock snapshot. */
+ cs_state =
+ bt_message_packet_end_borrow_default_clock_snapshot_const(
+ in_message, &cs);
+
+ /* Create an outpute packet end message. */
+ BT_ASSERT(cs_state == BT_CLOCK_SNAPSHOT_STATE_KNOWN);
+ out_message = bt_message_packet_end_create_with_default_clock_snapshot(
+ debug_it->input_iterator, out_packet,
+ bt_clock_snapshot_get_value(cs));
+ } else {
+ out_message = bt_message_packet_end_create(
+ debug_it->input_iterator, out_packet);
+ }
+
+ if (!out_message) {
+ BT_LOGE("Error creating output packet end message: "
+ "out-p-addr=%p", out_packet);
+ }
+
+ /* Remove packet from data mapping hashtable. */
+ trace_ir_mapping_remove_mapped_packet(debug_it->ir_maps, in_packet);
+
+ return out_message;
+}
+
+static
+bt_message *handle_msg_iterator_inactivity(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ /*
+ * This message type can be forwarded directly because it does
+ * not refer to any objects in the trace class.
+ */
+ bt_message_get_ref(in_message);
+ return (bt_message*) in_message;
+}
+
+static
+bt_message *handle_stream_act_begin_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_clock_snapshot *cs;
+ const bt_clock_class *default_cc;
+ bt_message *out_message = NULL;
+ bt_stream *out_stream;
+ uint64_t cs_value;
+ bt_message_stream_activity_clock_snapshot_state cs_state;
+
+ const bt_stream *in_stream =
+ bt_message_stream_activity_beginning_borrow_stream_const(
+ in_message);
+ BT_ASSERT(in_stream);
+
+ out_stream = trace_ir_mapping_borrow_mapped_stream(debug_it->ir_maps,
+ in_stream);
+ BT_ASSERT(out_stream);
+
+ out_message = bt_message_stream_activity_beginning_create(
+ debug_it->input_iterator, out_stream);
+ if (!out_message) {
+ BT_LOGE("Error creating output stream activity beginning "
+ "message: out-s-addr=%p", out_stream);
+ goto error;
+ }
+
+ default_cc = bt_stream_class_borrow_default_clock_class_const(
+ bt_stream_borrow_class_const(in_stream));
+ if (default_cc) {
+ /* Borrow clock snapshot. */
+ cs_state =
+ bt_message_stream_activity_beginning_borrow_default_clock_snapshot_const(
+ in_message, &cs);
+
+ if (cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN) {
+ cs_value = bt_clock_snapshot_get_value(cs);
+ bt_message_stream_activity_beginning_set_default_clock_snapshot(
+ out_message, cs_value);
+ } else {
+ bt_message_stream_activity_beginning_set_default_clock_snapshot_state(
+ out_message, cs_state);
+ }
+ }
+
+error:
+ return out_message;
+}
+
+static
+bt_message *handle_stream_act_end_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_clock_snapshot *cs;
+ const bt_clock_class *default_cc;
+ const bt_stream *in_stream;
+ bt_message *out_message;
+ bt_stream *out_stream;
+ uint64_t cs_value;
+ bt_message_stream_activity_clock_snapshot_state cs_state;
+
+ in_stream = bt_message_stream_activity_end_borrow_stream_const(
+ in_message);
+ BT_ASSERT(in_stream);
+
+ out_stream = trace_ir_mapping_borrow_mapped_stream(debug_it->ir_maps, in_stream);
+ BT_ASSERT(out_stream);
+
+ out_message = bt_message_stream_activity_end_create(
+ debug_it->input_iterator, out_stream);
+ if (!out_message) {
+ BT_LOGE("Error creating output stream activity end message: "
+ "out-s-addr=%p", out_stream);
+ goto error;
+ }
+
+ default_cc = bt_stream_class_borrow_default_clock_class_const(
+ bt_stream_borrow_class_const(in_stream));
+
+ if (default_cc) {
+ cs_state =
+ bt_message_stream_activity_end_borrow_default_clock_snapshot_const(
+ in_message, &cs);
+
+ if (cs_state == BT_MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN ) {
+ cs_value = bt_clock_snapshot_get_value(cs);
+ bt_message_stream_activity_end_set_default_clock_snapshot(
+ out_message, cs_value);
+ } else {
+ bt_message_stream_activity_end_set_default_clock_snapshot_state(
+ out_message, cs_state);
+ }
+ }
+
+error:
+ return out_message;
+}
+
+static
+bt_message *handle_discarded_events_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_clock_snapshot *begin_cs, *end_cs;
+ const bt_stream *in_stream;
+ const bt_clock_class *default_cc;
+ uint64_t discarded_events, begin_cs_value, end_cs_value;
+ bt_clock_snapshot_state begin_cs_state, end_cs_state;
+ bt_property_availability prop_avail;
+ bt_message *out_message = NULL;
+ bt_stream *out_stream;
+
+ in_stream = bt_message_discarded_events_borrow_stream_const(
+ in_message);
+ BT_ASSERT(in_stream);
+
+ out_stream = trace_ir_mapping_borrow_mapped_stream(
+ debug_it->ir_maps, in_stream);
+ BT_ASSERT(out_stream);
+
+ default_cc = bt_stream_class_borrow_default_clock_class_const(
+ bt_stream_borrow_class_const(in_stream));
+ if (default_cc) {
+ begin_cs_state =
+ bt_message_discarded_events_borrow_default_beginning_clock_snapshot_const(
+ in_message, &begin_cs);
+ end_cs_state =
+ bt_message_discarded_events_borrow_default_end_clock_snapshot_const(
+ in_message, &end_cs);
+ /*
+ * Both clock snapshots should be known as we check that the
+ * all input stream classes have an always known clock. Unknown
+ * clock is not yet supported.
+ */
+ BT_ASSERT(begin_cs_state == BT_CLOCK_SNAPSHOT_STATE_KNOWN &&
+ end_cs_state == BT_CLOCK_SNAPSHOT_STATE_KNOWN);
+
+ begin_cs_value = bt_clock_snapshot_get_value(begin_cs);
+ end_cs_value = bt_clock_snapshot_get_value(end_cs);
+
+ out_message =
+ bt_message_discarded_events_create_with_default_clock_snapshots(
+ debug_it->input_iterator, out_stream,
+ begin_cs_value, end_cs_value);
+ } else {
+ out_message = bt_message_discarded_events_create(
+ debug_it->input_iterator, out_stream);
+ }
+ if (!out_message) {
+ BT_LOGE("Error creating output discarded events message: "
+ "out-s-addr=%p", out_stream);
+ goto error;
+ }
+
+ prop_avail = bt_message_discarded_events_get_count(in_message,
+ &discarded_events);
+
+ if (prop_avail == BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE) {
+ bt_message_discarded_events_set_count(out_message,
+ discarded_events);
+ }
+
+error:
+ return out_message;
+}
+
+static
+bt_message *handle_discarded_packets_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ const bt_clock_snapshot *begin_cs, *end_cs;
+ const bt_clock_class *default_cc;
+ const bt_stream *in_stream;
+ uint64_t discarded_packets, begin_cs_value, end_cs_value;
+ bt_clock_snapshot_state begin_cs_state, end_cs_state;
+ bt_property_availability prop_avail;
+ bt_message *out_message = NULL;
+ bt_stream *out_stream;
+
+ in_stream = bt_message_discarded_packets_borrow_stream_const(
+ in_message);
+ BT_ASSERT(in_stream);
+
+ out_stream = trace_ir_mapping_borrow_mapped_stream(
+ debug_it->ir_maps, in_stream);
+ BT_ASSERT(out_stream);
+
+ default_cc = bt_stream_class_borrow_default_clock_class_const(
+ bt_stream_borrow_class_const(in_stream));
+ if (default_cc) {
+ begin_cs_state =
+ bt_message_discarded_packets_borrow_default_beginning_clock_snapshot_const(
+ in_message, &begin_cs);
+
+ end_cs_state =
+ bt_message_discarded_packets_borrow_default_end_clock_snapshot_const(
+ in_message, &end_cs);
+
+ /*
+ * Both clock snapshots should be known as we check that the
+ * all input stream classes have an always known clock. Unknown
+ * clock is not yet supported.
+ */
+ BT_ASSERT(begin_cs_state == BT_CLOCK_SNAPSHOT_STATE_KNOWN &&
+ end_cs_state == BT_CLOCK_SNAPSHOT_STATE_KNOWN);
+
+ begin_cs_value = bt_clock_snapshot_get_value(begin_cs);
+ end_cs_value = bt_clock_snapshot_get_value(end_cs);
+
+ out_message = bt_message_discarded_packets_create_with_default_clock_snapshots(
+ debug_it->input_iterator, out_stream,
+ begin_cs_value, end_cs_value);
+ } else {
+ out_message = bt_message_discarded_packets_create(
+ debug_it->input_iterator, out_stream);
+ }
+ if (!out_message) {
+ BT_LOGE("Error creating output discarded packet message: "
+ "out-s-addr=%p", out_stream);
+ goto error;
+ }
+
+ prop_avail = bt_message_discarded_packets_get_count(in_message,
+ &discarded_packets);
+ if (prop_avail == BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE) {
+ bt_message_discarded_packets_set_count(out_message,
+ discarded_packets);
+ }
+
+error:
+ return out_message;
+}
+
+static
+const bt_message *handle_message(struct debug_info_msg_iter *debug_it,
+ const bt_message *in_message)
+{
+ bt_message *out_message = NULL;
+
+ switch (bt_message_get_type(in_message)) {
+ case BT_MESSAGE_TYPE_EVENT:
+ out_message = handle_event_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_PACKET_BEGINNING:
+ out_message = handle_packet_begin_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_PACKET_END:
+ out_message = handle_packet_end_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_STREAM_BEGINNING:
+ out_message = handle_stream_begin_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_STREAM_END:
+ out_message = handle_stream_end_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY:
+ out_message = handle_msg_iterator_inactivity(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING:
+ out_message = handle_stream_act_begin_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_STREAM_ACTIVITY_END:
+ out_message = handle_stream_act_end_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_DISCARDED_EVENTS:
+ out_message = handle_discarded_events_message(debug_it,
+ in_message);
+ break;
+ case BT_MESSAGE_TYPE_DISCARDED_PACKETS:
+ out_message = handle_discarded_packets_message(debug_it,
+ in_message);
+ break;
+ default:
+ abort();
+ break;
+ }
+
+ return out_message;
+}
+
+static
+int init_from_params(struct debug_info_component *debug_info_component,
+ const bt_value *params)
+{
+ const bt_value *value = NULL;
+ int ret = 0;
+
+ BT_ASSERT(params);
+
+ value = bt_value_map_borrow_entry_value_const(params,
+ "debug-info-field-name");
+ if (value) {
+ debug_info_component->arg_debug_info_field_name =
+ g_strdup(bt_value_string_get(value));
+ } else {
+ debug_info_component->arg_debug_info_field_name =
+ g_strdup(DEFAULT_DEBUG_INFO_FIELD_NAME);
+ }
+
+ value = bt_value_map_borrow_entry_value_const(params, "debug-info-dir");
+ if (value) {
+ debug_info_component->arg_debug_dir =
+ g_strdup(bt_value_string_get(value));
+ } else {
+ debug_info_component->arg_debug_dir = NULL;
+ }
+
+
+ value = bt_value_map_borrow_entry_value_const(params, "target-prefix");
+ if (value) {
+ debug_info_component->arg_target_prefix =
+ g_strdup(bt_value_string_get(value));
+ } else {
+ debug_info_component->arg_target_prefix = NULL;
+ }
+
+ value = bt_value_map_borrow_entry_value_const(params, "full-path");
+ if (value) {
+ debug_info_component->arg_full_path = bt_value_bool_get(value);
+ } else {
+ debug_info_component->arg_full_path = BT_FALSE;
+ }
+
+ return ret;
+}
+
+BT_HIDDEN
+bt_self_component_status debug_info_comp_init(
+ bt_self_component_filter *self_comp,
+ const bt_value *params, UNUSED_VAR void *init_method_data)
+{
+ int ret;
+ struct debug_info_component *debug_info_comp;
+ bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
+
+ BT_LOGD("Initializing debug_info component: "
+ "comp-addr=%p, params-addr=%p", self_comp, params);
+
+ debug_info_comp = g_new0(struct debug_info_component, 1);
+ if (!debug_info_comp) {
+ BT_LOGE_STR("Failed to allocate one debug_info component.");
+ goto error;
+ }
+
+ bt_self_component_set_data(
+ bt_self_component_filter_as_self_component(self_comp),
+ debug_info_comp);
+
+ status = bt_self_component_filter_add_input_port(self_comp, "in",
+ NULL, NULL);
+ if (status != BT_SELF_COMPONENT_STATUS_OK) {
+ goto error;
+ }
+
+ status = bt_self_component_filter_add_output_port(self_comp, "out",
+ NULL, NULL);
+ if (status != BT_SELF_COMPONENT_STATUS_OK) {
+ goto error;
+ }
+
+ ret = init_from_params(debug_info_comp, params);
+ if (ret) {
+ BT_LOGE("Cannot configure debug_info component: "
+ "debug_info-comp-addr=%p, params-addr=%p",
+ debug_info_comp, params);
+ goto error;
+ }
+
+ goto end;
+
+error:
+ destroy_debug_info_comp(debug_info_comp);
+ bt_self_component_set_data(
+ bt_self_component_filter_as_self_component(self_comp),
+ NULL);
+
+ if (status == BT_SELF_COMPONENT_STATUS_OK) {
+ status = BT_SELF_COMPONENT_STATUS_ERROR;
+ }
+end:
+ return status;
+}
+
+BT_HIDDEN
+void debug_info_comp_finalize(bt_self_component_filter *self_comp)
+{
+ struct debug_info_component *debug_info =
+ bt_self_component_get_data(
+ bt_self_component_filter_as_self_component(
+ self_comp));
+ BT_LOGD("Finalizing debug_info self_component: comp-addr=%p",
+ self_comp);
+
+ destroy_debug_info_comp(debug_info);
+}
+
+BT_HIDDEN
+bt_self_message_iterator_status debug_info_msg_iter_next(
+ bt_self_message_iterator *self_msg_iter,
+ const bt_message_array_const msgs, uint64_t capacity,
+ uint64_t *count)
+{
+ bt_self_component_port_input_message_iterator *upstream_iterator = NULL;
+ bt_message_iterator_status upstream_iterator_ret_status;
+ struct debug_info_msg_iter *debug_info_msg_iter;
+ struct debug_info_component *debug_info = NULL;
+ bt_self_message_iterator_status status;
+ bt_self_component *self_comp = NULL;
+ bt_message_array_const input_msgs;
+ const bt_message *out_message;
+ uint64_t curr_msg_idx, i;
+
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_OK;
+
+ self_comp = bt_self_message_iterator_borrow_component(self_msg_iter);
+ BT_ASSERT(self_comp);
+
+ debug_info = bt_self_component_get_data(self_comp);
+ BT_ASSERT(debug_info);
+
+ debug_info_msg_iter = bt_self_message_iterator_get_data(self_msg_iter);
+ BT_ASSERT(debug_info_msg_iter);
+
+ upstream_iterator = debug_info_msg_iter->msg_iter;
+ BT_ASSERT(upstream_iterator);
+
+ upstream_iterator_ret_status =
+ bt_self_component_port_input_message_iterator_next(
+ upstream_iterator, &input_msgs, count);
+ if (upstream_iterator_ret_status != BT_MESSAGE_ITERATOR_STATUS_OK) {
+ /*
+ * No messages were returned. Not necessarily an error. Convert
+ * the upstream message iterator status to a self status.
+ */
+ status = bt_common_message_iterator_status_to_self(
+ upstream_iterator_ret_status);
+ goto end;
+ }
+
+ /*
+ * There should never be more received messages than the capacity we
+ * provided.
+ */
+ BT_ASSERT(*count <= capacity);
+
+ for (curr_msg_idx = 0; curr_msg_idx < *count; curr_msg_idx++) {
+ out_message = handle_message(debug_info_msg_iter,
+ input_msgs[curr_msg_idx]);
+ if (!out_message) {
+ goto handle_msg_error;
+ }
+
+ msgs[curr_msg_idx] = out_message;
+ /*
+ * Drop our reference of the input message as we are done with
+ * it and created a output copy.
+ */
+ bt_message_put_ref(input_msgs[curr_msg_idx]);
+ }
+
+ goto end;
+
+handle_msg_error:
+ /*
+ * Drop references of all the output messages created before the
+ * failure.
+ */
+ for (i = 0; i < curr_msg_idx; i++) {
+ bt_message_put_ref(msgs[i]);
+ }
+
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM;
+end:
+ return status;
+}
+
+BT_HIDDEN
+bt_self_message_iterator_status debug_info_msg_iter_init(
+ bt_self_message_iterator *self_msg_iter,
+ bt_self_component_filter *self_comp,
+ bt_self_component_port_output *self_port)
+{
+ bt_self_message_iterator_status status = BT_SELF_MESSAGE_ITERATOR_STATUS_OK;
+ struct bt_self_component_port_input *input_port;
+ bt_self_component_port_input_message_iterator *upstream_iterator;
+ struct debug_info_msg_iter *debug_info_msg_iter;
+ gchar *debug_info_field_name;
+
+ /* Borrow the upstream input port. */
+ input_port = bt_self_component_filter_borrow_input_port_by_name(
+ self_comp, "in");
+ if (!input_port) {
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR;
+ goto end;
+ }
+
+ /* Create an iterator on the upstream component. */
+ upstream_iterator = bt_self_component_port_input_message_iterator_create(
+ input_port);
+ if (!upstream_iterator) {
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM;
+ goto end;
+ }
+
+ debug_info_msg_iter = g_new0(struct debug_info_msg_iter, 1);
+ if (!debug_info_msg_iter) {
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM;
+ goto end;
+ }
+
+ /* Create hashtable to will contain debug info mapping. */
+ debug_info_msg_iter->debug_info_map = g_hash_table_new_full(
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) debug_info_destroy);
+ if (!debug_info_msg_iter->debug_info_map) {
+ g_free(debug_info_msg_iter);
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM;
+ goto end;
+ }
+
+ debug_info_msg_iter->self_comp =
+ bt_self_component_filter_as_self_component(self_comp);
+
+ BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_MOVE_REF(
+ debug_info_msg_iter->msg_iter, upstream_iterator);
+
+ debug_info_msg_iter->debug_info_component = bt_self_component_get_data(
+ bt_self_component_filter_as_self_component(
+ self_comp));
+
+ debug_info_field_name =
+ debug_info_msg_iter->debug_info_component->arg_debug_info_field_name;
+
+ debug_info_msg_iter->ir_maps = trace_ir_maps_create(
+ bt_self_component_filter_as_self_component(self_comp),
+ debug_info_field_name);
+ if (!debug_info_msg_iter->ir_maps) {
+ g_hash_table_destroy(debug_info_msg_iter->debug_info_map);
+ g_free(debug_info_msg_iter);
+ status = BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM;
+ goto end;
+ }
+
+ bt_self_message_iterator_set_data(self_msg_iter, debug_info_msg_iter);
+
+ debug_info_msg_iter->input_iterator = self_msg_iter;
+
+end:
+ return status;
+}
+
+BT_HIDDEN
+bt_bool debug_info_msg_iter_can_seek_beginning(
+ bt_self_message_iterator *self_msg_iter)
+{
+ struct debug_info_msg_iter *debug_info_msg_iter =
+ bt_self_message_iterator_get_data(self_msg_iter);
+ BT_ASSERT(debug_info_msg_iter);
+
+ return bt_self_component_port_input_message_iterator_can_seek_beginning(
+ debug_info_msg_iter->msg_iter);
+}
+
+BT_HIDDEN
+bt_self_message_iterator_status debug_info_msg_iter_seek_beginning(
+ bt_self_message_iterator *self_msg_iter)
+{
+ struct debug_info_msg_iter *debug_info_msg_iter =
+ bt_self_message_iterator_get_data(self_msg_iter);
+ bt_message_iterator_status status = BT_MESSAGE_ITERATOR_STATUS_OK;
+
+ BT_ASSERT(debug_info_msg_iter);
+
+ /* Ask the upstream component to seek to the beginning. */
+ status = bt_self_component_port_input_message_iterator_seek_beginning(
+ debug_info_msg_iter->msg_iter);
+ if (status != BT_MESSAGE_ITERATOR_STATUS_OK) {
+ goto end;
+ }
+
+ /* Clear this iterator data. */
+ trace_ir_maps_clear(debug_info_msg_iter->ir_maps);
+ g_hash_table_remove_all(debug_info_msg_iter->debug_info_map);
+end:
+ return bt_common_message_iterator_status_to_self(status);
+}
+
+BT_HIDDEN
+void debug_info_msg_iter_finalize(bt_self_message_iterator *it)
+{
+ struct debug_info_msg_iter *debug_info_msg_iter;
+
+ debug_info_msg_iter = bt_self_message_iterator_get_data(it);
+ BT_ASSERT(debug_info_msg_iter);
+
+ bt_self_component_port_input_message_iterator_put_ref(
+ debug_info_msg_iter->msg_iter);
+
+ trace_ir_maps_destroy(debug_info_msg_iter->ir_maps);
+ g_hash_table_destroy(debug_info_msg_iter->debug_info_map);
+
+ g_free(debug_info_msg_iter);
+}