From 1e690349e56f6aed18afca0730159a6c374171c6 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Tue, 12 Dec 2023 04:17:44 +0000 Subject: [PATCH] ctf: add try/catch at entry points Add try / catch at the entry points of the CTF component classes to convert thrown exceptions in the proper statuses. The handled exceptions are: - std::bad_alloc: converted to MEMORY_ERROR - bt2::Error: converted to ERROR Any other exception (for example, coming from a third-party library we would eventually use) should be caught and converted to a bt2_common::Error. Change-Id: I06c2ccb43947f5a9e61568967f2812ccb0821b36 Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/12263 Tested-by: jenkins Reviewed-by: Philippe Proulx --- src/plugins/ctf/fs-sink/fs-sink.cpp | 244 +++++----- src/plugins/ctf/fs-src/fs.cpp | 239 ++++++---- src/plugins/ctf/lttng-live/lttng-live.cpp | 549 +++++++++++----------- 3 files changed, 554 insertions(+), 478 deletions(-) diff --git a/src/plugins/ctf/fs-sink/fs-sink.cpp b/src/plugins/ctf/fs-sink/fs-sink.cpp index c6d5029c..52d3d426 100644 --- a/src/plugins/ctf/fs-sink/fs-sink.cpp +++ b/src/plugins/ctf/fs-sink/fs-sink.cpp @@ -132,58 +132,64 @@ bt_component_class_initialize_method_status ctf_fs_sink_init(bt_self_component_s bt_self_component_sink_configuration *, const bt_value *params, void *) { - bt_component_class_initialize_method_status status; - bt_self_component_add_port_status add_port_status; - struct fs_sink_comp *fs_sink = NULL; - bt_self_component *self_comp = bt_self_component_sink_as_self_component(self_comp_sink); - - fs_sink = new fs_sink_comp {bt2::SelfSinkComponent {self_comp_sink}}; - fs_sink->output_dir_path = g_string_new(NULL); - status = configure_component(fs_sink, params); - if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - /* configure_component() logs errors */ - goto end; - } + try { + bt_component_class_initialize_method_status status; + bt_self_component_add_port_status add_port_status; + struct fs_sink_comp *fs_sink = NULL; + bt_self_component *self_comp = bt_self_component_sink_as_self_component(self_comp_sink); + + fs_sink = new fs_sink_comp {bt2::SelfSinkComponent {self_comp_sink}}; + fs_sink->output_dir_path = g_string_new(NULL); + status = configure_component(fs_sink, params); + if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + /* configure_component() logs errors */ + goto end; + } - if (fs_sink->assume_single_trace && - g_file_test(fs_sink->output_dir_path->str, G_FILE_TEST_EXISTS)) { - BT_CPPLOGE_APPEND_CAUSE_SPEC( - fs_sink->logger, "Single trace mode, but output path exists: output-path=\"{}\"", - fs_sink->output_dir_path->str); - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - goto end; - } + if (fs_sink->assume_single_trace && + g_file_test(fs_sink->output_dir_path->str, G_FILE_TEST_EXISTS)) { + BT_CPPLOGE_APPEND_CAUSE_SPEC( + fs_sink->logger, "Single trace mode, but output path exists: output-path=\"{}\"", + fs_sink->output_dir_path->str); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + goto end; + } - status = ensure_output_dir_exists(fs_sink); - if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - /* ensure_output_dir_exists() logs errors */ - goto end; - } + status = ensure_output_dir_exists(fs_sink); + if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + /* ensure_output_dir_exists() logs errors */ + goto end; + } - fs_sink->traces = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify) fs_sink_trace_destroy); - if (!fs_sink->traces) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to allocate one GHashTable."); - status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto end; - } + fs_sink->traces = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify) fs_sink_trace_destroy); + if (!fs_sink->traces) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to allocate one GHashTable."); + status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto end; + } - add_port_status = - bt_self_component_sink_add_input_port(self_comp_sink, in_port_name, NULL, NULL); - if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { - status = (bt_component_class_initialize_method_status) add_port_status; - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to add input port."); - goto end; - } + add_port_status = + bt_self_component_sink_add_input_port(self_comp_sink, in_port_name, NULL, NULL); + if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { + status = (bt_component_class_initialize_method_status) add_port_status; + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to add input port."); + goto end; + } - bt_self_component_set_data(self_comp, fs_sink); + bt_self_component_set_data(self_comp, fs_sink); end: - if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - destroy_fs_sink_comp(fs_sink); - } + if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + destroy_fs_sink_comp(fs_sink); + } - return status; + return status; + } catch (const std::bad_alloc&) { + return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + } } static inline struct fs_sink_stream *borrow_stream(struct fs_sink_comp *fs_sink, @@ -224,37 +230,39 @@ end: static inline bt_component_class_sink_consume_method_status handle_event_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) { - int ret; - bt_component_class_sink_consume_method_status status = - BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; - const bt_event *ir_event = bt_message_event_borrow_event_const(msg); - const bt_stream *ir_stream = bt_event_borrow_stream_const(ir_event); - struct fs_sink_stream *stream; - struct fs_sink_ctf_event_class *ec = NULL; - const bt_clock_snapshot *cs = NULL; - - stream = borrow_stream(fs_sink, ir_stream); - if (G_UNLIKELY(!stream)) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to borrow stream."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } + try { + int ret; + bt_component_class_sink_consume_method_status status = + BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK; + const bt_event *ir_event = bt_message_event_borrow_event_const(msg); + const bt_stream *ir_stream = bt_event_borrow_stream_const(ir_event); + struct fs_sink_stream *stream; + struct fs_sink_ctf_event_class *ec = NULL; + const bt_clock_snapshot *cs = NULL; + + stream = borrow_stream(fs_sink, ir_stream); + if (G_UNLIKELY(!stream)) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to borrow stream."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } - ret = try_translate_event_class_trace_ir_to_ctf_ir(fs_sink, stream->sc, - bt_event_borrow_class_const(ir_event), &ec); - if (ret) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to translate event class to CTF IR."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } + ret = try_translate_event_class_trace_ir_to_ctf_ir( + fs_sink, stream->sc, bt_event_borrow_class_const(ir_event), &ec); + if (ret) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, + "Failed to translate event class to CTF IR."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } - BT_ASSERT_DBG(ec); + BT_ASSERT_DBG(ec); - if (stream->sc->default_clock_class) { - cs = bt_message_event_borrow_default_clock_snapshot_const(msg); - } + if (stream->sc->default_clock_class) { + cs = bt_message_event_borrow_default_clock_snapshot_const(msg); + } - /* + /* * If this event's stream does not support packets, then we * lazily create artificial packets. * @@ -263,43 +271,49 @@ handle_event_msg(struct fs_sink_comp *fs_sink, const bt_message *msg) * comes the time to write a new event and the packet's content * size is >= 4 MiB), except the last one which can be smaller. */ - if (G_UNLIKELY(!stream->sc->has_packets)) { - if (stream->packet_state.is_open && - bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser) / 8 >= 4 * 1024 * 1024) { - /* + if (G_UNLIKELY(!stream->sc->has_packets)) { + if (stream->packet_state.is_open && + bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser) / 8 >= + 4 * 1024 * 1024) { + /* * Stream's current packet is larger than 4 MiB: * close it. A new packet will be opened just * below. */ - ret = fs_sink_stream_close_packet(stream, NULL); - if (ret) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to close packet."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; + ret = fs_sink_stream_close_packet(stream, NULL); + if (ret) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to close packet."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } } - } - if (!stream->packet_state.is_open) { - /* Stream's packet is not currently opened: open it */ - ret = fs_sink_stream_open_packet(stream, NULL, NULL); - if (ret) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to open packet."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; + if (!stream->packet_state.is_open) { + /* Stream's packet is not currently opened: open it */ + ret = fs_sink_stream_open_packet(stream, NULL, NULL); + if (ret) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to open packet."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } } } - } - BT_ASSERT_DBG(stream->packet_state.is_open); - ret = fs_sink_stream_write_event(stream, cs, ir_event, ec); - if (G_UNLIKELY(ret)) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to write event."); - status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; - goto end; - } + BT_ASSERT_DBG(stream->packet_state.is_open); + ret = fs_sink_stream_write_event(stream, cs, ir_event, ec); + if (G_UNLIKELY(ret)) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to write event."); + status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + goto end; + } end: - return status; + return status; + } catch (const std::bad_alloc&) { + return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR; + } } static inline bt_component_class_sink_consume_method_status @@ -1008,23 +1022,29 @@ end: bt_component_class_sink_graph_is_configured_method_status ctf_fs_sink_graph_is_configured(bt_self_component_sink *self_comp) { - bt_component_class_sink_graph_is_configured_method_status status; - bt_message_iterator_create_from_sink_component_status msg_iter_status; - fs_sink_comp *fs_sink = (fs_sink_comp *) bt_self_component_get_data( - bt_self_component_sink_as_self_component(self_comp)); - - msg_iter_status = bt_message_iterator_create_from_sink_component( - self_comp, bt_self_component_sink_borrow_input_port_by_name(self_comp, in_port_name), - &fs_sink->upstream_iter); - if (msg_iter_status != BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) { - status = (bt_component_class_sink_graph_is_configured_method_status) msg_iter_status; - BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to create upstream iterator."); - goto end; - } + try { + bt_component_class_sink_graph_is_configured_method_status status; + bt_message_iterator_create_from_sink_component_status msg_iter_status; + fs_sink_comp *fs_sink = (fs_sink_comp *) bt_self_component_get_data( + bt_self_component_sink_as_self_component(self_comp)); + + msg_iter_status = bt_message_iterator_create_from_sink_component( + self_comp, bt_self_component_sink_borrow_input_port_by_name(self_comp, in_port_name), + &fs_sink->upstream_iter); + if (msg_iter_status != BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) { + status = (bt_component_class_sink_graph_is_configured_method_status) msg_iter_status; + BT_CPPLOGE_APPEND_CAUSE_SPEC(fs_sink->logger, "Failed to create upstream iterator."); + goto end; + } - status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK; + status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK; end: - return status; + return status; + } catch (const std::bad_alloc&) { + return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2c::Error&) { + return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR; + } } void ctf_fs_sink_finalize(bt_self_component_sink *self_comp) diff --git a/src/plugins/ctf/fs-src/fs.cpp b/src/plugins/ctf/fs-src/fs.cpp index 8a8fb434..1161cb2f 100644 --- a/src/plugins/ctf/fs-src/fs.cpp +++ b/src/plugins/ctf/fs-src/fs.cpp @@ -100,31 +100,32 @@ bt_message_iterator_class_next_method_status ctf_fs_iterator_next(bt_self_message_iterator *iterator, bt_message_array_const msgs, uint64_t capacity, uint64_t *count) { - bt_message_iterator_class_next_method_status status; - struct ctf_fs_msg_iter_data *msg_iter_data = - (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(iterator); - uint64_t i = 0; + try { + bt_message_iterator_class_next_method_status status; + struct ctf_fs_msg_iter_data *msg_iter_data = + (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(iterator); + uint64_t i = 0; - if (G_UNLIKELY(msg_iter_data->next_saved_error)) { - /* + if (G_UNLIKELY(msg_iter_data->next_saved_error)) { + /* * Last time we were called, we hit an error but had some * messages to deliver, so we stashed the error here. Return * it now. */ - BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(msg_iter_data->next_saved_error); - status = msg_iter_data->next_saved_status; - goto end; - } - - do { - status = ctf_fs_iterator_next_one(msg_iter_data, &msgs[i]); - if (status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK) { - i++; + BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(msg_iter_data->next_saved_error); + status = msg_iter_data->next_saved_status; + goto end; } - } while (i < capacity && status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK); - if (i > 0) { - /* + do { + status = ctf_fs_iterator_next_one(msg_iter_data, &msgs[i]); + if (status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK) { + i++; + } + } while (i < capacity && status == BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK); + + if (i > 0) { + /* * Even if ctf_fs_iterator_next_one() returned something * else than BT_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK, we * accumulated message objects in the output @@ -135,38 +136,50 @@ ctf_fs_iterator_next(bt_self_message_iterator *iterator, bt_message_array_const * called, possibly without any accumulated * message, in which case we'll return it. */ - if (status < 0) { - /* + if (status < 0) { + /* * Save this error for the next _next call. Assume that * this component always appends error causes when * returning an error status code, which will cause the * current thread error to be non-NULL. */ - msg_iter_data->next_saved_error = bt_current_thread_take_error(); - BT_ASSERT(msg_iter_data->next_saved_error); - msg_iter_data->next_saved_status = status; - } + msg_iter_data->next_saved_error = bt_current_thread_take_error(); + BT_ASSERT(msg_iter_data->next_saved_error); + msg_iter_data->next_saved_status = status; + } - *count = i; - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; - } + *count = i; + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; + } end: - return status; + return status; + return status; + } catch (const std::bad_alloc&) { + return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + } } bt_message_iterator_class_seek_beginning_method_status ctf_fs_iterator_seek_beginning(bt_self_message_iterator *it) { - struct ctf_fs_msg_iter_data *msg_iter_data = - (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(it); + try { + struct ctf_fs_msg_iter_data *msg_iter_data = + (struct ctf_fs_msg_iter_data *) bt_self_message_iterator_get_data(it); - BT_ASSERT(msg_iter_data); + BT_ASSERT(msg_iter_data); - ctf_msg_iter_reset(msg_iter_data->msg_iter); - ctf_fs_ds_group_medops_data_reset(msg_iter_data->msg_iter_medops_data); + ctf_msg_iter_reset(msg_iter_data->msg_iter); + ctf_fs_ds_group_medops_data_reset(msg_iter_data->msg_iter_medops_data); - return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK; + return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK; + } catch (const std::bad_alloc&) { + return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_ERROR; + } } void ctf_fs_iterator_finalize(bt_self_message_iterator *it) @@ -197,62 +210,68 @@ ctf_fs_iterator_init(bt_self_message_iterator *self_msg_iter, bt_self_message_iterator_configuration *config, bt_self_component_port_output *self_port) { - struct ctf_fs_port_data *port_data; - bt_message_iterator_class_initialize_method_status status; - enum ctf_msg_iter_medium_status medium_status; - - port_data = (struct ctf_fs_port_data *) bt_self_component_port_get_data( - bt_self_component_port_output_as_self_component_port(self_port)); - BT_ASSERT(port_data); - - ctf_fs_msg_iter_data *msg_iter_data = new ctf_fs_msg_iter_data {self_msg_iter}; - msg_iter_data->ds_file_group = port_data->ds_file_group; - - medium_status = ctf_fs_ds_group_medops_data_create(msg_iter_data->ds_file_group, self_msg_iter, - msg_iter_data->logger, - &msg_iter_data->msg_iter_medops_data); - BT_ASSERT(medium_status == CTF_MSG_ITER_MEDIUM_STATUS_OK || - medium_status == CTF_MSG_ITER_MEDIUM_STATUS_ERROR || - medium_status == CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR); - if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(msg_iter_data->logger, - "Failed to create ctf_fs_ds_group_medops"); - status = ctf_msg_iter_medium_status_to_msg_iter_initialize_status(medium_status); - goto error; - } + try { + struct ctf_fs_port_data *port_data; + bt_message_iterator_class_initialize_method_status status; + enum ctf_msg_iter_medium_status medium_status; + + port_data = (struct ctf_fs_port_data *) bt_self_component_port_get_data( + bt_self_component_port_output_as_self_component_port(self_port)); + BT_ASSERT(port_data); + + ctf_fs_msg_iter_data *msg_iter_data = new ctf_fs_msg_iter_data {self_msg_iter}; + msg_iter_data->ds_file_group = port_data->ds_file_group; + + medium_status = ctf_fs_ds_group_medops_data_create(msg_iter_data->ds_file_group, + self_msg_iter, msg_iter_data->logger, + &msg_iter_data->msg_iter_medops_data); + BT_ASSERT(medium_status == CTF_MSG_ITER_MEDIUM_STATUS_OK || + medium_status == CTF_MSG_ITER_MEDIUM_STATUS_ERROR || + medium_status == CTF_MSG_ITER_MEDIUM_STATUS_MEMORY_ERROR); + if (medium_status != CTF_MSG_ITER_MEDIUM_STATUS_OK) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(msg_iter_data->logger, + "Failed to create ctf_fs_ds_group_medops"); + status = ctf_msg_iter_medium_status_to_msg_iter_initialize_status(medium_status); + goto error; + } - msg_iter_data->msg_iter = ctf_msg_iter_create( - msg_iter_data->ds_file_group->ctf_fs_trace->metadata->tc, - bt_common_get_page_size(static_cast(msg_iter_data->logger.level())) * 8, - ctf_fs_ds_group_medops, msg_iter_data->msg_iter_medops_data, self_msg_iter, - msg_iter_data->logger); - if (!msg_iter_data->msg_iter) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(msg_iter_data->logger, - "Cannot create a CTF message iterator."); - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto error; - } + msg_iter_data->msg_iter = ctf_msg_iter_create( + msg_iter_data->ds_file_group->ctf_fs_trace->metadata->tc, + bt_common_get_page_size(static_cast(msg_iter_data->logger.level())) * 8, + ctf_fs_ds_group_medops, msg_iter_data->msg_iter_medops_data, self_msg_iter, + msg_iter_data->logger); + if (!msg_iter_data->msg_iter) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(msg_iter_data->logger, + "Cannot create a CTF message iterator."); + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto error; + } - /* + /* * This iterator can seek forward if its stream class has a default * clock class. */ - if (msg_iter_data->ds_file_group->sc->default_clock_class) { - bt_self_message_iterator_configuration_set_can_seek_forward(config, true); - } + if (msg_iter_data->ds_file_group->sc->default_clock_class) { + bt_self_message_iterator_configuration_set_can_seek_forward(config, true); + } - bt_self_message_iterator_set_data(self_msg_iter, msg_iter_data); - msg_iter_data = NULL; + bt_self_message_iterator_set_data(self_msg_iter, msg_iter_data); + msg_iter_data = NULL; - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; - goto end; + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; + goto end; error: - bt_self_message_iterator_set_data(self_msg_iter, NULL); + bt_self_message_iterator_set_data(self_msg_iter, NULL); end: - ctf_fs_msg_iter_data_destroy(msg_iter_data); - return status; + ctf_fs_msg_iter_data_destroy(msg_iter_data); + return status; + } catch (const std::bad_alloc&) { + return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + } } static void ctf_fs_trace_destroy(struct ctf_fs_trace *ctf_fs_trace) @@ -2218,16 +2237,22 @@ bt_component_class_initialize_method_status ctf_fs_init(bt_self_component_source bt_self_component_source_configuration *, const bt_value *params, void *) { - struct ctf_fs_component *ctf_fs; - bt_component_class_initialize_method_status ret = - BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; + try { + struct ctf_fs_component *ctf_fs; + bt_component_class_initialize_method_status ret = + BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK; + + ctf_fs = ctf_fs_create(params, self_comp_src); + if (!ctf_fs) { + ret = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + } - ctf_fs = ctf_fs_create(params, self_comp_src); - if (!ctf_fs) { - ret = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + return ret; + } catch (const std::bad_alloc&) { + return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; } - - return ret; } bt_component_class_query_method_status ctf_fs_query(bt_self_component_class_source *comp_class_src, @@ -2236,22 +2261,28 @@ bt_component_class_query_method_status ctf_fs_query(bt_self_component_class_sour __attribute__((unused)) void *method_data, const bt_value **result) { - bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - - bt2c::Logger logger {bt2::SelfComponentClass {comp_class_src}, - bt2::PrivateQueryExecutor {priv_query_exec}, "PLUGIN/SRC.CTF.FS/QUERY"}; - - if (strcmp(object, "metadata-info") == 0) { - status = metadata_info_query(params, logger, result); - } else if (strcmp(object, "babeltrace.trace-infos") == 0) { - status = trace_infos_query(params, logger, result); - } else if (!strcmp(object, "babeltrace.support-info")) { - status = support_info_query(params, logger, result); - } else { - BT_CPPLOGE_SPEC(logger, "Unknown query object `{}`", object); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; - goto end; - } + try { + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt2c::Logger logger {bt2::SelfComponentClass {comp_class_src}, + bt2::PrivateQueryExecutor {priv_query_exec}, + "PLUGIN/SRC.CTF.FS/QUERY"}; + + if (strcmp(object, "metadata-info") == 0) { + status = metadata_info_query(params, logger, result); + } else if (strcmp(object, "babeltrace.trace-infos") == 0) { + status = trace_infos_query(params, logger, result); + } else if (!strcmp(object, "babeltrace.support-info")) { + status = support_info_query(params, logger, result); + } else { + BT_CPPLOGE_SPEC(logger, "Unknown query object `{}`", object); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; + goto end; + } end: - return status; + return status; + } catch (const std::bad_alloc&) { + return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + } } diff --git a/src/plugins/ctf/lttng-live/lttng-live.cpp b/src/plugins/ctf/lttng-live/lttng-live.cpp index ba524f26..7e32c379 100644 --- a/src/plugins/ctf/lttng-live/lttng-live.cpp +++ b/src/plugins/ctf/lttng-live/lttng-live.cpp @@ -1424,20 +1424,21 @@ bt_message_iterator_class_next_method_status lttng_live_msg_iter_next(bt_self_message_iterator *self_msg_it, bt_message_array_const msgs, uint64_t capacity, uint64_t *count) { - bt_message_iterator_class_next_method_status status; - enum lttng_live_viewer_status viewer_status; - struct lttng_live_msg_iter *lttng_live_msg_iter = - (struct lttng_live_msg_iter *) bt_self_message_iterator_get_data(self_msg_it); - struct lttng_live_component *lttng_live = lttng_live_msg_iter->lttng_live_comp; - enum lttng_live_iterator_status stream_iter_status; - uint64_t session_idx; + try { + bt_message_iterator_class_next_method_status status; + enum lttng_live_viewer_status viewer_status; + struct lttng_live_msg_iter *lttng_live_msg_iter = + (struct lttng_live_msg_iter *) bt_self_message_iterator_get_data(self_msg_it); + struct lttng_live_component *lttng_live = lttng_live_msg_iter->lttng_live_comp; + enum lttng_live_iterator_status stream_iter_status; + uint64_t session_idx; - *count = 0; + *count = 0; - BT_ASSERT_DBG(lttng_live_msg_iter); + BT_ASSERT_DBG(lttng_live_msg_iter); - if (G_UNLIKELY(lttng_live_msg_iter->was_interrupted)) { - /* + if (G_UNLIKELY(lttng_live_msg_iter->was_interrupted)) { + /* * The iterator was interrupted in a previous call to the * `_next()` method. We currently do not support generating * messages after such event. The babeltrace2 CLI should never @@ -1445,55 +1446,55 @@ lttng_live_msg_iter_next(bt_self_message_iterator *self_msg_it, bt_message_array * is to prevent other graph users from using this live * iterator in an messed up internal state. */ - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; - BT_CPPLOGE_APPEND_CAUSE_SPEC( - lttng_live_msg_iter->logger, - "Message iterator was interrupted during a previous call to the `next()` and currently does not support continuing after such event."); - goto end; - } + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + BT_CPPLOGE_APPEND_CAUSE_SPEC( + lttng_live_msg_iter->logger, + "Message iterator was interrupted during a previous call to the `next()` and currently does not support continuing after such event."); + goto end; + } - /* + /* * Clear all the invalid message reference that might be left over in * the output array. */ - memset(msgs, 0, capacity * sizeof(*msgs)); + memset(msgs, 0, capacity * sizeof(*msgs)); - /* + /* * If no session are exposed on the relay found at the url provided by * the user, session count will be 0. In this case, we return status * end to return gracefully. */ - if (lttng_live_msg_iter->sessions->len == 0) { - if (lttng_live->params.sess_not_found_act != SESSION_NOT_FOUND_ACTION_CONTINUE) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; - goto end; - } else { - /* + if (lttng_live_msg_iter->sessions->len == 0) { + if (lttng_live->params.sess_not_found_act != SESSION_NOT_FOUND_ACTION_CONTINUE) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; + goto end; + } else { + /* * The are no more active session for this session * name. Retry to create a viewer session for the * requested session name. */ - viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, - "Error creating LTTng live viewer session"); - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; - } else { - bt_common_abort(); + viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, + "Error creating LTTng live viewer session"); + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; + } else { + bt_common_abort(); + } + goto end; } - goto end; } } - } - if (lttng_live_msg_iter->active_stream_iter == 0) { - lttng_live_force_new_streams_and_metadata(lttng_live_msg_iter); - } + if (lttng_live_msg_iter->active_stream_iter == 0) { + lttng_live_force_new_streams_and_metadata(lttng_live_msg_iter); + } - /* + /* * Here the muxing of message is done. * * We need to iterate over all the streams of all the traces of all the @@ -1512,117 +1513,117 @@ lttng_live_msg_iter_next(bt_self_message_iterator *self_msg_it, bt_message_array * sessions to pick the message with the smallest timestamp and we * return it. */ - while (*count < capacity) { - struct lttng_live_stream_iterator *youngest_stream_iter = NULL, - *candidate_stream_iter = NULL; - int64_t youngest_msg_ts_ns = INT64_MAX; - - BT_ASSERT_DBG(lttng_live_msg_iter->sessions); - session_idx = 0; - while (session_idx < lttng_live_msg_iter->sessions->len) { - struct lttng_live_session *session = (lttng_live_session *) g_ptr_array_index( - lttng_live_msg_iter->sessions, session_idx); - - /* Find the best candidate message to send downstream. */ - stream_iter_status = next_stream_iterator_for_session(lttng_live_msg_iter, session, - &candidate_stream_iter); - - /* If we receive an END status, it means that either: + while (*count < capacity) { + struct lttng_live_stream_iterator *youngest_stream_iter = NULL, + *candidate_stream_iter = NULL; + int64_t youngest_msg_ts_ns = INT64_MAX; + + BT_ASSERT_DBG(lttng_live_msg_iter->sessions); + session_idx = 0; + while (session_idx < lttng_live_msg_iter->sessions->len) { + struct lttng_live_session *session = (lttng_live_session *) g_ptr_array_index( + lttng_live_msg_iter->sessions, session_idx); + + /* Find the best candidate message to send downstream. */ + stream_iter_status = next_stream_iterator_for_session(lttng_live_msg_iter, session, + &candidate_stream_iter); + + /* If we receive an END status, it means that either: * - Those traces never had active streams (UST with no * data produced yet), * - All live stream iterators have ENDed.*/ - if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { - if (session->closed && session->traces->len == 0) { - /* + if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) { + if (session->closed && session->traces->len == 0) { + /* * Remove the session from the list. * session_idx is not modified since * g_ptr_array_remove_index_fast * replaces the the removed element with * the array's last element. */ - g_ptr_array_remove_index_fast(lttng_live_msg_iter->sessions, session_idx); - } else { - session_idx++; + g_ptr_array_remove_index_fast(lttng_live_msg_iter->sessions, session_idx); + } else { + session_idx++; + } + continue; } - continue; - } - if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { - goto return_status; - } + if (stream_iter_status != LTTNG_LIVE_ITERATOR_STATUS_OK) { + goto return_status; + } - if (G_UNLIKELY(youngest_stream_iter == NULL) || - candidate_stream_iter->current_msg_ts_ns < youngest_msg_ts_ns) { - youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; - youngest_stream_iter = candidate_stream_iter; - } else if (candidate_stream_iter->current_msg_ts_ns == youngest_msg_ts_ns) { - /* + if (G_UNLIKELY(youngest_stream_iter == NULL) || + candidate_stream_iter->current_msg_ts_ns < youngest_msg_ts_ns) { + youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; + youngest_stream_iter = candidate_stream_iter; + } else if (candidate_stream_iter->current_msg_ts_ns == youngest_msg_ts_ns) { + /* * The currently selected message to be sent * downstream next has the exact same timestamp * that of the current candidate message. We * must break the tie in a predictable manner. */ - BT_CPPLOGD_STR_SPEC( - lttng_live_msg_iter->logger, - "Two of the next message candidates have the same timestamps, pick one deterministically."); - /* + BT_CPPLOGD_STR_SPEC( + lttng_live_msg_iter->logger, + "Two of the next message candidates have the same timestamps, pick one deterministically."); + /* * Order the messages in an arbitrary but * deterministic way. */ - int ret = common_muxing_compare_messages(candidate_stream_iter->current_msg, - youngest_stream_iter->current_msg); - if (ret < 0) { - /* + int ret = common_muxing_compare_messages(candidate_stream_iter->current_msg, + youngest_stream_iter->current_msg); + if (ret < 0) { + /* * The `candidate_stream_iter->current_msg` * should go first. Update the next * iterator and the current timestamp. */ - youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; - youngest_stream_iter = candidate_stream_iter; - } else if (ret == 0) { - /* Unable to pick which one should go first. */ - BT_CPPLOGW_SPEC( - lttng_live_msg_iter->logger, - "Cannot deterministically pick next live stream message iterator because they have identical next messages: " - "next-stream-iter-addr={}" - "candidate-stream-iter-addr={}", - fmt::ptr(youngest_stream_iter), fmt::ptr(candidate_stream_iter)); + youngest_msg_ts_ns = candidate_stream_iter->current_msg_ts_ns; + youngest_stream_iter = candidate_stream_iter; + } else if (ret == 0) { + /* Unable to pick which one should go first. */ + BT_CPPLOGW_SPEC( + lttng_live_msg_iter->logger, + "Cannot deterministically pick next live stream message iterator because they have identical next messages: " + "next-stream-iter-addr={}" + "candidate-stream-iter-addr={}", + fmt::ptr(youngest_stream_iter), fmt::ptr(candidate_stream_iter)); + } } - } - session_idx++; - } + session_idx++; + } - if (!youngest_stream_iter) { - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; - goto return_status; - } + if (!youngest_stream_iter) { + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; + goto return_status; + } - BT_ASSERT_DBG(youngest_stream_iter->current_msg); - /* Ensure monotonicity. */ - BT_ASSERT_DBG(lttng_live_msg_iter->last_msg_ts_ns <= - youngest_stream_iter->current_msg_ts_ns); + BT_ASSERT_DBG(youngest_stream_iter->current_msg); + /* Ensure monotonicity. */ + BT_ASSERT_DBG(lttng_live_msg_iter->last_msg_ts_ns <= + youngest_stream_iter->current_msg_ts_ns); - /* + /* * Insert the next message to the message batch. This will set * stream iterator current message to NULL so that next time * we fetch the next message of that stream iterator */ - BT_MESSAGE_MOVE_REF(msgs[*count], youngest_stream_iter->current_msg); - (*count)++; + BT_MESSAGE_MOVE_REF(msgs[*count], youngest_stream_iter->current_msg); + (*count)++; - /* Update the last timestamp in nanoseconds sent downstream. */ - lttng_live_msg_iter->last_msg_ts_ns = youngest_msg_ts_ns; - youngest_stream_iter->current_msg_ts_ns = INT64_MAX; + /* Update the last timestamp in nanoseconds sent downstream. */ + lttng_live_msg_iter->last_msg_ts_ns = youngest_msg_ts_ns; + youngest_stream_iter->current_msg_ts_ns = INT64_MAX; - stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; - } + stream_iter_status = LTTNG_LIVE_ITERATOR_STATUS_OK; + } return_status: - switch (stream_iter_status) { - case LTTNG_LIVE_ITERATOR_STATUS_OK: - case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: - /* + switch (stream_iter_status) { + case LTTNG_LIVE_ITERATOR_STATUS_OK: + case LTTNG_LIVE_ITERATOR_STATUS_AGAIN: + /* * If we gathered messages, return _OK even if the graph was * interrupted. This allows for the components downstream to at * least get the those messages. If the graph was indeed @@ -1630,40 +1631,45 @@ return_status: * application will tear down the graph. This component class * doesn't support restarting after an interruption. */ - if (*count > 0) { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; - } else { - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; - } - break; - case LTTNG_LIVE_ITERATOR_STATUS_END: - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; - break; - case LTTNG_LIVE_ITERATOR_STATUS_NOMEM: - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, - "Memory error preparing the next batch of messages: " - "live-iter-status={}", - stream_iter_status); - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; - break; - case LTTNG_LIVE_ITERATOR_STATUS_ERROR: - case LTTNG_LIVE_ITERATOR_STATUS_INVAL: - case LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED: - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, - "Error preparing the next batch of messages: " - "live-iter-status={}", - stream_iter_status); + if (*count > 0) { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK; + } else { + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN; + } + break; + case LTTNG_LIVE_ITERATOR_STATUS_END: + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END; + break; + case LTTNG_LIVE_ITERATOR_STATUS_NOMEM: + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, + "Memory error preparing the next batch of messages: " + "live-iter-status={}", + stream_iter_status); + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; + break; + case LTTNG_LIVE_ITERATOR_STATUS_ERROR: + case LTTNG_LIVE_ITERATOR_STATUS_INVAL: + case LTTNG_LIVE_ITERATOR_STATUS_UNSUPPORTED: + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, + "Error preparing the next batch of messages: " + "live-iter-status={}", + stream_iter_status); - status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; - /* Put all existing messages on error. */ - put_messages(msgs, *count); - break; - default: - bt_common_abort(); - } + status = BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + /* Put all existing messages on error. */ + put_messages(msgs, *count); + break; + default: + bt_common_abort(); + } end: - return status; + return status; + } catch (const std::bad_alloc&) { + return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; + } } static struct lttng_live_msg_iter * @@ -1690,105 +1696,111 @@ bt_message_iterator_class_initialize_method_status lttng_live_msg_iter_init(bt_self_message_iterator *self_msg_it, bt_self_message_iterator_configuration *, bt_self_component_port_output *) { - bt_message_iterator_class_initialize_method_status status; - struct lttng_live_component *lttng_live; - struct lttng_live_msg_iter *lttng_live_msg_iter; - enum lttng_live_viewer_status viewer_status; - bt_self_component *self_comp = bt_self_message_iterator_borrow_component(self_msg_it); - - lttng_live = (lttng_live_component *) bt_self_component_get_data(self_comp); - - /* There can be only one downstream iterator at the same time. */ - BT_ASSERT(!lttng_live->has_msg_iter); - lttng_live->has_msg_iter = true; - - lttng_live_msg_iter = lttng_live_msg_iter_create(lttng_live, self_msg_it); - if (!lttng_live_msg_iter) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live->logger, "Failed to create lttng_live_msg_iter"); - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; - goto error; - } + try { + bt_message_iterator_class_initialize_method_status status; + struct lttng_live_component *lttng_live; + struct lttng_live_msg_iter *lttng_live_msg_iter; + enum lttng_live_viewer_status viewer_status; + bt_self_component *self_comp = bt_self_message_iterator_borrow_component(self_msg_it); + + lttng_live = (lttng_live_component *) bt_self_component_get_data(self_comp); + + /* There can be only one downstream iterator at the same time. */ + BT_ASSERT(!lttng_live->has_msg_iter); + lttng_live->has_msg_iter = true; + + lttng_live_msg_iter = lttng_live_msg_iter_create(lttng_live, self_msg_it); + if (!lttng_live_msg_iter) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live->logger, + "Failed to create lttng_live_msg_iter"); + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + goto error; + } - viewer_status = live_viewer_connection_create(lttng_live->params.url->str, false, - lttng_live_msg_iter, lttng_live_msg_iter->logger, - <tng_live_msg_iter->viewer_connection); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, - "Failed to create viewer connection"); - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - /* + viewer_status = live_viewer_connection_create( + lttng_live->params.url->str, false, lttng_live_msg_iter, lttng_live_msg_iter->logger, + <tng_live_msg_iter->viewer_connection); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, + "Failed to create viewer connection"); + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + /* * Interruption in the _iter_init() method is not * supported. Return an error. */ - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, - "Interrupted while creating viewer connection"); - } + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, + "Interrupted while creating viewer connection"); + } - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - goto error; - } + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + goto error; + } - viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); - if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { - if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, - "Failed to create viewer session"); - } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { - /* + viewer_status = lttng_live_create_viewer_session(lttng_live_msg_iter); + if (viewer_status != LTTNG_LIVE_VIEWER_STATUS_OK) { + if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_ERROR) { + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, + "Failed to create viewer session"); + } else if (viewer_status == LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED) { + /* * Interruption in the _iter_init() method is not * supported. Return an error. */ - BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, - "Interrupted when creating viewer session"); - } - - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; - goto error; - } + BT_CPPLOGE_APPEND_CAUSE_SPEC(lttng_live_msg_iter->logger, + "Interrupted when creating viewer session"); + } - if (lttng_live_msg_iter->sessions->len == 0) { - switch (lttng_live->params.sess_not_found_act) { - case SESSION_NOT_FOUND_ACTION_CONTINUE: - BT_CPPLOGI_SPEC( - lttng_live_msg_iter->logger, - "Unable to connect to the requested live viewer session. Keep " - "trying to connect because of {}=\"{}\" component parameter: url=\"{}\"", - SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_CONTINUE_STR, - lttng_live->params.url->str); - break; - case SESSION_NOT_FOUND_ACTION_FAIL: - BT_CPPLOGE_APPEND_CAUSE_SPEC( - lttng_live_msg_iter->logger, - "Unable to connect to the requested live viewer session. Fail " - "the message iterator initialization because of {}=\"{}\" " - "component parameter: url =\"{}\"", - SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_FAIL_STR, - lttng_live->params.url->str); status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; goto error; - case SESSION_NOT_FOUND_ACTION_END: - BT_CPPLOGI_SPEC( - lttng_live_msg_iter->logger, - "Unable to connect to the requested live viewer session. End gracefully at the first _next() " - "call because of {}=\"{}\" component parameter: " - "url=\"{}\"", - SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_END_STR, - lttng_live->params.url->str); - break; - default: - bt_common_abort(); } - } - bt_self_message_iterator_set_data(self_msg_it, lttng_live_msg_iter); - status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; - goto end; + if (lttng_live_msg_iter->sessions->len == 0) { + switch (lttng_live->params.sess_not_found_act) { + case SESSION_NOT_FOUND_ACTION_CONTINUE: + BT_CPPLOGI_SPEC( + lttng_live_msg_iter->logger, + "Unable to connect to the requested live viewer session. " + "Keep trying to connect because of {}=\"{}\" component parameter: url=\"{}\"", + SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_CONTINUE_STR, + lttng_live->params.url->str); + break; + case SESSION_NOT_FOUND_ACTION_FAIL: + BT_CPPLOGE_APPEND_CAUSE_SPEC( + lttng_live_msg_iter->logger, + "Unable to connect to the requested live viewer session. " + "Fail the message iterator initialization because of {}=\"{}\" " + "component parameter: url =\"{}\"", + SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_FAIL_STR, + lttng_live->params.url->str); + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + goto error; + case SESSION_NOT_FOUND_ACTION_END: + BT_CPPLOGI_SPEC(lttng_live_msg_iter->logger, + "Unable to connect to the requested live viewer session. " + "End gracefully at the first _next() call because of {}=\"{}\"" + " component parameter: url=\"{}\"", + SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_END_STR, + lttng_live->params.url->str); + break; + default: + bt_common_abort(); + } + } + + bt_self_message_iterator_set_data(self_msg_it, lttng_live_msg_iter); + status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK; + goto end; error: - lttng_live_msg_iter_destroy(lttng_live_msg_iter); + lttng_live_msg_iter_destroy(lttng_live_msg_iter); end: - return status; + return status; + } catch (const std::bad_alloc&) { + return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + } } static struct bt_param_validation_map_value_entry_descr list_sessions_params[] = { @@ -1936,23 +1948,29 @@ bt_component_class_query_method_status lttng_live_query(bt_self_component_class_ __attribute__((unused)) void *method_data, const bt_value **result) { - bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; - bt2c::Logger logger {bt2::SelfComponentClass {comp_class}, - bt2::PrivateQueryExecutor {priv_query_exec}, - "PLUGIN/SRC.CTF.LTTNG-LIVE/QUERY"}; - - if (strcmp(object, "sessions") == 0) { - status = lttng_live_query_list_sessions(params, result, logger); - } else if (strcmp(object, "babeltrace.support-info") == 0) { - status = lttng_live_query_support_info(params, result, logger); - } else { - BT_CPPLOGI_SPEC(logger, "Unknown query object `{}`", object); - status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; - goto end; - } + try { + bt_component_class_query_method_status status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; + bt2c::Logger logger {bt2::SelfComponentClass {comp_class}, + bt2::PrivateQueryExecutor {priv_query_exec}, + "PLUGIN/SRC.CTF.LTTNG-LIVE/QUERY"}; + + if (strcmp(object, "sessions") == 0) { + status = lttng_live_query_list_sessions(params, result, logger); + } else if (strcmp(object, "babeltrace.support-info") == 0) { + status = lttng_live_query_support_info(params, result, logger); + } else { + BT_CPPLOGI_SPEC(logger, "Unknown query object `{}`", object); + status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT; + goto end; + } end: - return status; + return status; + } catch (const std::bad_alloc&) { + return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; + } } static void lttng_live_component_destroy_data(struct lttng_live_component *lttng_live) @@ -2079,28 +2097,35 @@ bt_component_class_initialize_method_status lttng_live_component_init(bt_self_component_source *self_comp_src, bt_self_component_source_configuration *, const bt_value *params, void *) { - struct lttng_live_component *lttng_live; - bt_component_class_initialize_method_status ret; - bt_self_component *self_comp = bt_self_component_source_as_self_component(self_comp_src); - bt_self_component_add_port_status add_port_status; + try { + struct lttng_live_component *lttng_live; + bt_component_class_initialize_method_status ret; + bt_self_component *self_comp = bt_self_component_source_as_self_component(self_comp_src); + bt_self_component_add_port_status add_port_status; + + ret = lttng_live_component_create(params, self_comp_src, <tng_live); + if (ret != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { + goto error; + } - ret = lttng_live_component_create(params, self_comp_src, <tng_live); - if (ret != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) { - goto error; - } + add_port_status = + bt_self_component_source_add_output_port(self_comp_src, "out", NULL, NULL); + if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { + ret = (bt_component_class_initialize_method_status) add_port_status; + goto end; + } - add_port_status = bt_self_component_source_add_output_port(self_comp_src, "out", NULL, NULL); - if (add_port_status != BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) { - ret = (bt_component_class_initialize_method_status) add_port_status; + bt_self_component_set_data(self_comp, lttng_live); goto end; - } - - bt_self_component_set_data(self_comp, lttng_live); - goto end; error: - lttng_live_component_destroy_data(lttng_live); - lttng_live = NULL; + lttng_live_component_destroy_data(lttng_live); + lttng_live = NULL; end: - return ret; + return ret; + } catch (const std::bad_alloc&) { + return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR; + } catch (const bt2::Error&) { + return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; + } } -- 2.34.1