X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Flttng-utils%2Fcopy.c;h=f99d38315bfe6c79016a81e46ea3397526fd84f0;hb=b4d4912ff0147ecc7f4f3b714529337a4a4e4095;hp=385d55c46027c8cba7801494ccfa55cb3c55ab56;hpb=34101229f363ec19ce2deac84f138e393474595f;p=babeltrace.git diff --git a/plugins/lttng-utils/copy.c b/plugins/lttng-utils/copy.c index 385d55c4..f99d3831 100644 --- a/plugins/lttng-utils/copy.c +++ b/plugins/lttng-utils/copy.c @@ -26,7 +26,11 @@ * SOFTWARE. */ +#define BT_LOG_TAG "PLUGIN-LTTNG-UTILS-DEBUG-INFO-FLT-COPY" +#include "logging.h" + #include +#include #include #include #include @@ -40,38 +44,66 @@ #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) +{ + bt_put(stream); +} + +static +void unref_packet(struct bt_ctf_packet *packet) +{ + bt_put(packet); +} + +static +void unref_stream_class(struct bt_ctf_stream_class *stream_class) +{ + bt_put(stream_class); +} + +static +void unref_debug_info(struct debug_info *debug_info) +{ + debug_info_destroy(debug_info); +} + +static +void destroy_stream_state_key(gpointer key) +{ + g_free((enum fs_writer_stream_state *) key); +} + static struct bt_ctf_field *get_payload_field(FILE *err, struct bt_ctf_event *event, const char *field_name) { - struct bt_ctf_field *field = NULL, *sec = NULL; - struct bt_ctf_field_type *sec_type = NULL; + struct bt_ctf_field *field = NULL, *payload = NULL; + struct bt_ctf_field_type *payload_type = NULL; - sec = bt_ctf_event_get_payload(event, NULL); - if (!sec) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto end; - } + payload = bt_ctf_event_get_payload(event, NULL); + assert(payload); - sec_type = bt_ctf_field_get_type(sec); - if (!sec_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto end; - } + payload_type = bt_ctf_field_get_type(payload); + assert(payload_type); - if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + if (bt_ctf_field_type_get_type_id(payload_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) { + BT_LOGE("Wrong type, expected struct: field-name=\"%s\"", + field_name); goto end; } - field = bt_ctf_field_structure_get_field(sec, field_name); + field = bt_ctf_field_structure_get_field(payload, field_name); end: - bt_put(sec_type); - bt_put(sec); + bt_put(payload_type); + bt_put(payload); return field; } @@ -84,21 +116,15 @@ struct bt_ctf_field *get_stream_event_context_field(FILE *err, sec = bt_ctf_event_get_stream_event_context(event); if (!sec) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); goto end; } sec_type = bt_ctf_field_get_type(sec); - if (!sec_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto end; - } + assert(sec_type); if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected struct, field-name=\"%s\"", + field_name); goto end; } @@ -121,31 +147,30 @@ int get_stream_event_context_unsigned_int_field_value(FILE *err, field = get_stream_event_context_field(err, event, field_name); if (!field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); goto error; } field_type = bt_ctf_field_get_type(field); - if (!field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected integer: field-name=\"%s\"", + field_name); goto error; } if (bt_ctf_field_type_integer_get_signed(field_type) != 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected unsigned integer: field-name=\"%s\"", + field_name); goto error; } ret = bt_ctf_field_unsigned_integer_get_value(field, value); + if (ret) { + BT_LOGE("Failed to get value: field-name=\"%s\"", + field_name); + goto error; + } goto end; error: @@ -170,21 +195,16 @@ int get_stream_event_context_int_field_value(FILE *err, struct bt_ctf_event *eve } field_type = bt_ctf_field_get_type(field); - if (!field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected integer: field-name=\"%s\"", field_name); goto error; } if (bt_ctf_field_type_integer_get_signed(field_type) != 1) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected signed integer: field-name=\"%s\"", + field_name); goto error; } @@ -210,31 +230,31 @@ int get_payload_unsigned_int_field_value(FILE *err, field = get_payload_field(err, event, field_name); if (!field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get payload: field-name=\"%s\"", field_name); goto error; } field_type = bt_ctf_field_get_type(field); - if (!field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected integer: field-name=\"%s\"", + field_name); goto error; } if (bt_ctf_field_type_integer_get_signed(field_type) != 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected unsigned integer: field-name=\"%s\"", + field_name); goto error; } ret = bt_ctf_field_unsigned_integer_get_value(field, value); + if (ret) { + BT_LOGE("Failed to get value: field-name=\"%s\"", + field_name); + goto error; + } goto end; error: @@ -255,31 +275,30 @@ int get_payload_int_field_value(FILE *err, struct bt_ctf_event *event, field = get_payload_field(err, event, field_name); if (!field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get payload: field-name=\"%s\"", field_name); goto error; } field_type = bt_ctf_field_get_type(field); - if (!field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected integer: field-name=\"%s\"", field_name); goto error; } if (bt_ctf_field_type_integer_get_signed(field_type) != 1) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected signed integer field-name=\"%s\"", + field_name); goto error; } ret = bt_ctf_field_signed_integer_get_value(field, value); + if (ret) { + BT_LOGE("Failed to get value: field-name=\"%s\"", + field_name); + goto error; + } goto end; error: @@ -299,30 +318,27 @@ int get_payload_string_field_value(FILE *err, struct bt_ctf_field_type *field_type = NULL; int ret; + /* + * The field might not exist, no error here. + */ field = get_payload_field(err, event, field_name); if (!field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); goto error; } field_type = bt_ctf_field_get_type(field); - if (!field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_STRING) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected string: field-name=\"%s\"", + field_name); goto error; } *value = bt_ctf_field_string_get_value(field); if (!*value) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get value: field-name=\"%s\"", + field_name); goto error; } @@ -352,44 +368,33 @@ int get_payload_build_id_field_value(FILE *err, field = get_payload_field(err, event, field_name); if (!field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get payload: field-name=\"%s\"", field_name); goto error; } field_type = bt_ctf_field_get_type(field); - if (!field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(field_type); if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_SEQUENCE) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Wrong type, expected sequence: field-name=\"%s\"", field_name); goto error; } BT_PUT(field_type); seq_len = bt_ctf_field_sequence_get_length(field); - if (!seq_len) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(seq_len); ret = bt_ctf_field_unsigned_integer_get_value(seq_len, build_id_len); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get value: field-name=\"%s\"", + field_name); goto error; } BT_PUT(seq_len); *build_id = g_new0(uint8_t, *build_id_len); if (!*build_id) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to allocate build_id."); goto error; } @@ -398,17 +403,18 @@ int get_payload_build_id_field_value(FILE *err, seq_field = bt_ctf_field_sequence_get_field(field, i); if (!seq_field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get field in sequence: sequence-name=\"%s\", index=%" PRIu64, + field_name, i); goto error; } ret = bt_ctf_field_unsigned_integer_get_value(seq_field, &tmp); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get value: field-name=\"%s\"", + field_name); goto error; } + BT_PUT(seq_field); (*build_id)[i] = (uint8_t) tmp; } @@ -426,16 +432,18 @@ end: static struct debug_info *lookup_trace_debug_info(struct debug_info_iterator *debug_it, - struct bt_ctf_trace *writer_trace) + struct bt_ctf_trace *writer_trace, + struct debug_info_trace *di_trace) { return (struct debug_info *) g_hash_table_lookup( - debug_it->trace_debug_map, + di_trace->trace_debug_map, (gpointer) writer_trace); } static struct debug_info *insert_new_debug_info(struct debug_info_iterator *debug_it, - struct bt_ctf_trace *writer_trace) + struct bt_ctf_trace *writer_trace, + struct debug_info_trace *di_trace) { struct debug_info *debug_info = NULL; struct bt_value *field = NULL; @@ -449,11 +457,8 @@ struct debug_info *insert_new_debug_info(struct debug_info_iterator *debug_it, goto end; } ret = bt_value_string_get(field, &str_value); - if (ret != BT_VALUE_STATUS_OK) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto end; - } + assert(ret == BT_VALUE_STATUS_OK); + /* Domain not ust, no debug info */ if (strcmp(str_value, "ust") != 0) { goto end; @@ -468,11 +473,8 @@ struct debug_info *insert_new_debug_info(struct debug_info_iterator *debug_it, goto end; } ret = bt_value_string_get(field, &str_value); - if (ret != BT_VALUE_STATUS_OK) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto end; - } + assert(ret == BT_VALUE_STATUS_OK); + /* Tracer_name not lttng-ust, no debug info */ if (strcmp(str_value, "lttng-ust") != 0) { goto end; @@ -481,12 +483,11 @@ struct debug_info *insert_new_debug_info(struct debug_info_iterator *debug_it, debug_info = debug_info_create(debug_it->debug_info_component); if (!debug_info) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to create debug info."); goto end; } - g_hash_table_insert(debug_it->trace_debug_map, (gpointer) writer_trace, + g_hash_table_insert(di_trace->trace_debug_map, (gpointer) writer_trace, debug_info); end: @@ -496,83 +497,319 @@ end: static struct debug_info *get_trace_debug_info(struct debug_info_iterator *debug_it, - struct bt_ctf_trace *writer_trace) + struct bt_ctf_trace *writer_trace, + struct debug_info_trace *di_trace) { struct debug_info *debug_info; - debug_info = lookup_trace_debug_info(debug_it, writer_trace); + debug_info = lookup_trace_debug_info(debug_it, writer_trace, di_trace); if (debug_info) { goto end; } - debug_info = insert_new_debug_info(debug_it, writer_trace); + debug_info = insert_new_debug_info(debug_it, writer_trace, di_trace); end: return debug_info; } static -struct bt_ctf_trace *lookup_trace(struct debug_info_iterator *debug_it, +struct debug_info_trace *lookup_trace(struct debug_info_iterator *debug_it, struct bt_ctf_trace *trace) { - return (struct bt_ctf_trace *) g_hash_table_lookup( + return (struct debug_info_trace *) g_hash_table_lookup( debug_it->trace_map, (gpointer) trace); } static -struct bt_ctf_trace *insert_new_trace(struct debug_info_iterator *debug_it, - struct bt_ctf_trace *trace) { +enum debug_info_stream_state *insert_new_stream_state( + struct debug_info_iterator *debug_it, + struct debug_info_trace *di_trace, struct bt_ctf_stream *stream) +{ + enum debug_info_stream_state *v = NULL; + + v = g_new0(enum debug_info_stream_state, 1); + if (!v) { + BT_LOGE_STR("Failed to allocate debug_info_stream_state."); + goto end; + } + *v = DEBUG_INFO_UNKNOWN_STREAM; + + g_hash_table_insert(di_trace->stream_states, stream, v); + +end: + return v; +} + +static +void check_completed_trace(gpointer key, gpointer value, gpointer user_data) +{ + enum debug_info_stream_state *state = value; + int *trace_completed = user_data; + + if (*state != DEBUG_INFO_COMPLETED_STREAM) { + *trace_completed = 0; + } +} + +static +gboolean empty_ht(gpointer key, gpointer value, gpointer user_data) +{ + return TRUE; +} + +BT_HIDDEN +void debug_info_close_trace(struct debug_info_iterator *debug_it, + struct debug_info_trace *di_trace) +{ + if (di_trace->static_listener_id >= 0) { + bt_ctf_trace_remove_is_static_listener(di_trace->trace, + di_trace->static_listener_id); + } + + /* Empty the stream class HT. */ + g_hash_table_foreach_remove(di_trace->stream_class_map, + empty_ht, NULL); + g_hash_table_destroy(di_trace->stream_class_map); + + /* Empty the stream HT. */ + g_hash_table_foreach_remove(di_trace->stream_map, + empty_ht, NULL); + g_hash_table_destroy(di_trace->stream_map); + + /* Empty the stream state HT. */ + g_hash_table_foreach_remove(di_trace->stream_states, + empty_ht, NULL); + g_hash_table_destroy(di_trace->stream_states); + + /* Empty the packet HT. */ + g_hash_table_foreach_remove(di_trace->packet_map, + empty_ht, NULL); + g_hash_table_destroy(di_trace->packet_map); + + /* Empty the trace_debug HT. */ + g_hash_table_foreach_remove(di_trace->trace_debug_map, + empty_ht, NULL); + 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); + assert(stream_class); + + writer_stream_class = bt_ctf_stream_get_class(writer_stream); + assert(writer_stream_class); + + ret = ctf_copy_event_classes(debug_it->err, stream_class, + writer_stream_class); + if (ret != BT_COMPONENT_STATUS_OK) { + BT_LOGE_STR("Failed to copy event classes."); + 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, 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); + assert(stream); + + writer_stream = bt_ctf_trace_get_stream_by_index(writer_trace, i); + assert(writer_stream); + + ret = sync_event_classes(di_trace->debug_it, stream, writer_stream); + if (ret) { + BT_LOGE_STR("Failed to synchronize the event classes."); + 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, + check_completed_trace, &trace_completed); + if (trace_completed) { + debug_info_close_trace(di_trace->debug_it, di_trace); + g_hash_table_remove(di_trace->debug_it->trace_map, + di_trace->trace); + } + +error: + bt_put(writer_stream); + bt_put(stream); +} + +static +struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it, + struct bt_ctf_stream *stream) { struct bt_ctf_trace *writer_trace = NULL; - int ret; + 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(); if (!writer_trace) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to create a new trace."); goto error; } - g_hash_table_insert(debug_it->trace_map, (gpointer) trace, writer_trace); + + stream_class = bt_ctf_stream_get_class(stream); + assert(stream_class); + + trace = bt_ctf_stream_class_get_trace(stream_class); + assert(trace); ret = ctf_copy_trace(debug_it->err, trace, writer_trace); if (ret != BT_COMPONENT_STATUS_OK) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; + BT_LOGE_STR("Failed to copy CTF trace."); + goto error; + } + + di_trace = g_new0(struct debug_info_trace, 1); + if (!di_trace) { + BT_LOGE_STR("Failed to allocate debug_info_trace."); + goto error; + } + + di_trace->trace = trace; + di_trace->writer_trace = writer_trace; + di_trace->debug_info_component = debug_it->debug_info_component; + di_trace->debug_it = debug_it; + di_trace->stream_map = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, (GDestroyNotify) unref_stream); + di_trace->stream_class_map = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, (GDestroyNotify) unref_stream_class); + di_trace->packet_map = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, (GDestroyNotify) unref_packet); + di_trace->trace_debug_map = g_hash_table_new_full(g_direct_hash, + 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); + for (i = 0; i < nr_stream; i++) { + stream = bt_ctf_trace_get_stream_by_index(trace, i); + assert(stream); + + insert_new_stream_state(debug_it, di_trace, stream); + writer_stream = insert_new_stream(debug_it, stream, di_trace); + if (!writer_stream) { + BT_LOGE_STR("Failed to insert new stream."); + goto error; + } + bt_get(writer_stream); + ret = sync_event_classes(debug_it, stream, writer_stream); + if (ret) { + BT_LOGE_STR("Failed to synchronize event classes."); + goto error; + } + BT_PUT(writer_stream); + BT_PUT(stream); + } + + /* Check if the trace is already static or register a listener. */ + 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); + assert(ret >= 0); + di_trace->static_listener_id = ret; } + goto end; error: BT_PUT(writer_trace); + g_free(di_trace); + di_trace = NULL; end: - return writer_trace; + bt_put(stream); + bt_put(writer_stream); + bt_put(stream_class); + bt_put(trace); + return di_trace; } static struct bt_ctf_packet *lookup_packet(struct debug_info_iterator *debug_it, - struct bt_ctf_packet *packet) + struct bt_ctf_packet *packet, + struct debug_info_trace *di_trace) { return (struct bt_ctf_packet *) g_hash_table_lookup( - debug_it->packet_map, + di_trace->packet_map, (gpointer) packet); } static struct bt_ctf_packet *insert_new_packet(struct debug_info_iterator *debug_it, struct bt_ctf_packet *packet, - struct bt_ctf_stream *writer_stream) + struct bt_ctf_stream *writer_stream, + struct debug_info_trace *di_trace) { struct bt_ctf_packet *writer_packet; + int ret; writer_packet = bt_ctf_packet_create(writer_stream); if (!writer_packet) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto end; + BT_LOGE_STR("Failed to create new packet."); + goto error; + } + + ret = ctf_packet_copy_header(debug_it->err, packet, writer_packet); + if (ret) { + BT_LOGE_STR("Failed to copy packet header."); + goto error; } - g_hash_table_insert(debug_it->packet_map, (gpointer) packet, writer_packet); + g_hash_table_insert(di_trace->packet_map, (gpointer) packet, + writer_packet); + goto end; + +error: + BT_PUT(writer_packet); end: return writer_packet; } @@ -605,61 +842,53 @@ int add_debug_info_fields(FILE *err, debug_field_type = bt_ctf_field_type_structure_create(); if (!debug_field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to create debug_info structure."); goto error; } bin_field_type = bt_ctf_field_type_string_create(); if (!bin_field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to create string for field=bin."); goto error; } func_field_type = bt_ctf_field_type_string_create(); if (!func_field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to create string for field=func."); goto error; } src_field_type = bt_ctf_field_type_string_create(); if (!src_field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to create string for field=src."); goto error; } ret = bt_ctf_field_type_structure_add_field(debug_field_type, bin_field_type, "bin"); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to add a field to debug_info struct: field=bin."); goto error; } ret = bt_ctf_field_type_structure_add_field(debug_field_type, func_field_type, "func"); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to add a field to debug_info struct: field=func."); goto error; } ret = bt_ctf_field_type_structure_add_field(debug_field_type, src_field_type, "src"); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to add a field to debug_info struct: field=src."); goto error; } ret = bt_ctf_field_type_structure_add_field(writer_event_context_type, debug_field_type, component->arg_debug_info_field_name); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to add debug_info field to event_context."); goto error; } @@ -692,8 +921,8 @@ int create_debug_info_event_context_type(FILE *err, if (bt_ctf_field_type_structure_get_field(event_context_type, &field_name, &field_type, i) < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get a field from the event-context: field-name=\"%s\"", + field_name); goto error; } @@ -701,8 +930,8 @@ int create_debug_info_event_context_type(FILE *err, field_type, field_name); BT_PUT(field_type); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE("Failed to add a field to the event-context: field-name=\"%s\"", + field_name); goto error; } } @@ -729,62 +958,45 @@ struct bt_ctf_stream_class *copy_stream_class_debug_info(FILE *err, int ret_int; const char *name = bt_ctf_stream_class_get_name(stream_class); - if (strlen(name) == 0) { - name = NULL; - } - - writer_stream_class = bt_ctf_stream_class_create(name); + writer_stream_class = bt_ctf_stream_class_create_empty(name); if (!writer_stream_class) { - fprintf(err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to create empty stream class."); goto error; } type = bt_ctf_stream_class_get_packet_context_type(stream_class); - if (!type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; - } - - ret_int = bt_ctf_stream_class_set_packet_context_type( - writer_stream_class, type); - if (ret_int < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; + if (type) { + ret_int = bt_ctf_stream_class_set_packet_context_type( + writer_stream_class, type); + if (ret_int < 0) { + BT_LOGE_STR("Failed to set packet_context type."); + goto error; + } + BT_PUT(type); } - BT_PUT(type); type = bt_ctf_stream_class_get_event_header_type(stream_class); - if (!type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; - } - - ret_int = bt_ctf_stream_class_set_event_header_type( - writer_stream_class, type); - if (ret_int < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; + if (type) { + ret_int = bt_ctf_stream_class_set_event_header_type( + writer_stream_class, type); + if (ret_int < 0) { + BT_LOGE_STR("Failed to set event_header type."); + goto error; + } + BT_PUT(type); } - BT_PUT(type); type = bt_ctf_stream_class_get_event_context_type(stream_class); if (type) { writer_event_context_type = bt_ctf_field_type_structure_create(); if (!writer_event_context_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to create writer_event_context struct type."); goto error; } ret_int = create_debug_info_event_context_type(err, type, writer_event_context_type, component); if (ret_int) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to create debug_info event_context type."); goto error; } BT_PUT(type); @@ -792,8 +1004,7 @@ struct bt_ctf_stream_class *copy_stream_class_debug_info(FILE *err, ret_int = bt_ctf_stream_class_set_event_context_type( writer_stream_class, writer_event_context_type); if (ret_int < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to set event_context type."); goto error; } BT_PUT(writer_event_context_type); @@ -826,18 +1037,22 @@ int add_clock_classes(FILE *err, struct bt_ctf_trace *writer_trace, for (i = 0; i < clock_class_count; i++) { struct bt_ctf_clock_class *clock_class = bt_ctf_trace_get_clock_class_by_index(trace, i); + struct bt_ctf_clock_class *existing_clock_class = NULL; - if (!clock_class) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; + assert(clock_class); + + existing_clock_class = bt_ctf_trace_get_clock_class_by_name( + writer_trace, bt_ctf_clock_class_get_name(clock_class)); + bt_put(existing_clock_class); + if (existing_clock_class) { + bt_put(clock_class); + continue; } ret = bt_ctf_trace_add_clock_class(writer_trace, clock_class); BT_PUT(clock_class); if (ret != 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to add clock_class."); goto error; } } @@ -859,58 +1074,43 @@ struct bt_ctf_stream_class *insert_new_stream_class( { struct bt_ctf_stream_class *writer_stream_class = NULL; struct bt_ctf_trace *trace, *writer_trace = NULL; + struct debug_info_trace *di_trace; enum bt_component_status ret; int int_ret; trace = bt_ctf_stream_class_get_trace(stream_class); - if (!trace) { - fprintf(debug_it->err, - "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; - } + assert(trace); - writer_trace = lookup_trace(debug_it, trace); - if (!writer_trace) { - writer_trace = insert_new_trace(debug_it, trace); - if (!writer_trace) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - ret = BT_COMPONENT_STATUS_ERROR; - goto error; - } + di_trace = lookup_trace(debug_it, trace); + if (!di_trace) { + BT_LOGE_STR("Failed to find existing trace."); + ret = BT_COMPONENT_STATUS_ERROR; + goto error; } + writer_trace = di_trace->writer_trace; bt_get(writer_trace); writer_stream_class = copy_stream_class_debug_info(debug_it->err, stream_class, writer_trace, debug_it->debug_info_component); if (!writer_stream_class) { - fprintf(debug_it->err, "[error] Failed to copy stream class\n"); - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to copy stream class."); goto error; } int_ret = bt_ctf_trace_add_stream_class(writer_trace, writer_stream_class); if (int_ret) { - fprintf(debug_it->err, - "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to add stream class."); goto error; } ret = add_clock_classes(debug_it->err, writer_trace, writer_stream_class, trace); if (ret != BT_COMPONENT_STATUS_OK) { - fprintf(debug_it->err, - "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to add clock classes."); goto error; } - BT_PUT(writer_trace); - BT_PUT(trace); - g_hash_table_insert(debug_it->stream_class_map, + g_hash_table_insert(di_trace->stream_class_map, (gpointer) stream_class, writer_stream_class); goto end; @@ -926,36 +1126,47 @@ end: static struct bt_ctf_stream *insert_new_stream( struct debug_info_iterator *debug_it, - struct bt_ctf_stream_class *stream_class, - struct bt_ctf_stream *stream) + struct bt_ctf_stream *stream, + struct debug_info_trace *di_trace) { struct bt_ctf_stream *writer_stream = NULL; + struct bt_ctf_stream_class *stream_class = NULL; struct bt_ctf_stream_class *writer_stream_class = NULL; + int64_t id; + + stream_class = bt_ctf_stream_get_class(stream); + assert(stream_class); writer_stream_class = g_hash_table_lookup( - debug_it->stream_class_map, + di_trace->stream_class_map, (gpointer) stream_class); if (!writer_stream_class) { writer_stream_class = insert_new_stream_class(debug_it, stream_class); if (!writer_stream_class) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to insert new stream class."); goto error; } } bt_get(writer_stream_class); - writer_stream = bt_ctf_stream_create(writer_stream_class, - bt_ctf_stream_get_name(stream)); + id = bt_ctf_stream_get_id(stream); + if (id < 0) { + writer_stream = bt_ctf_stream_create(writer_stream_class, + bt_ctf_stream_get_name(stream)); + } else { + writer_stream = bt_ctf_stream_create_with_id( + writer_stream_class, + bt_ctf_stream_get_name(stream), id); + } + if (!writer_stream) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to create writer_stream."); goto error; } - g_hash_table_insert(debug_it->stream_map, (gpointer) stream, + g_hash_table_insert(di_trace->stream_map, (gpointer) stream, writer_stream); goto end; @@ -963,17 +1174,18 @@ struct bt_ctf_stream *insert_new_stream( error: BT_PUT(writer_stream); end: + bt_put(stream_class); bt_put(writer_stream_class); return writer_stream; } static struct bt_ctf_stream *lookup_stream(struct debug_info_iterator *debug_it, - struct bt_ctf_stream *stream) + struct bt_ctf_stream *stream, + struct debug_info_trace *di_trace) { return (struct bt_ctf_stream *) g_hash_table_lookup( - debug_it->stream_map, - (gpointer) stream); + di_trace->stream_map, (gpointer) stream); } static @@ -985,6 +1197,29 @@ struct bt_ctf_event_class *get_event_class(struct debug_info_iterator *debug_it, bt_ctf_event_class_get_id(event_class)); } +static +struct debug_info_trace *lookup_di_trace_from_stream( + struct debug_info_iterator *debug_it, + struct bt_ctf_stream *stream) +{ + struct bt_ctf_stream_class *stream_class = NULL; + struct bt_ctf_trace *trace = NULL; + struct debug_info_trace *di_trace = NULL; + + stream_class = bt_ctf_stream_get_class(stream); + assert(stream_class); + + trace = bt_ctf_stream_class_get_trace(stream_class); + assert(trace); + + di_trace = (struct debug_info_trace *) g_hash_table_lookup( + debug_it->trace_map, (gpointer) trace); + + BT_PUT(stream_class); + BT_PUT(trace); + return di_trace; +} + static struct bt_ctf_stream *get_writer_stream( struct debug_info_iterator *debug_it, @@ -992,17 +1227,21 @@ struct bt_ctf_stream *get_writer_stream( { struct bt_ctf_stream_class *stream_class = NULL; struct bt_ctf_stream *writer_stream = NULL; + struct debug_info_trace *di_trace = NULL; stream_class = bt_ctf_stream_get_class(stream); - if (!stream_class) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + assert(stream_class); + + di_trace = lookup_di_trace_from_stream(debug_it, stream); + if (!di_trace) { + BT_LOGE_STR("Failed to find existing trace from stream."); goto error; } - writer_stream = lookup_stream(debug_it, stream); + writer_stream = lookup_stream(debug_it, stream, di_trace); if (!writer_stream) { - writer_stream = insert_new_stream(debug_it, stream_class, stream); + BT_LOGE_STR("Failed to find existing stream."); + goto error; } bt_get(writer_stream); @@ -1021,21 +1260,23 @@ struct bt_ctf_packet *debug_info_new_packet( struct bt_ctf_packet *packet) { struct bt_ctf_stream *stream = NULL, *writer_stream = NULL; - struct bt_ctf_field *writer_packet_context = NULL; struct bt_ctf_packet *writer_packet = NULL; + struct bt_ctf_field *packet_context = NULL; + struct debug_info_trace *di_trace; int int_ret; stream = bt_ctf_packet_get_stream(packet); - if (!stream) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); - goto error; - } + assert(stream); writer_stream = get_writer_stream(debug_it, packet, stream); if (!writer_stream) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to get writer stream."); + goto error; + } + + di_trace = lookup_di_trace_from_stream(debug_it, stream); + if (!di_trace) { + BT_LOGE_STR("Failed to find existing trace from stream."); goto error; } @@ -1043,39 +1284,37 @@ struct bt_ctf_packet *debug_info_new_packet( * If a packet was already opened, close it and remove it from * the HT. */ - writer_packet = lookup_packet(debug_it, packet); + writer_packet = lookup_packet(debug_it, packet, di_trace); if (writer_packet) { - g_hash_table_remove(debug_it->packet_map, packet); + g_hash_table_remove(di_trace->packet_map, packet); BT_PUT(writer_packet); } - writer_packet = insert_new_packet(debug_it, packet, writer_stream); + writer_packet = insert_new_packet(debug_it, packet, writer_stream, + di_trace); if (!writer_packet) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to insert new packet."); goto error; } - writer_packet_context = ctf_copy_packet_context(debug_it->err, packet, - writer_stream, 0); - if (!writer_packet_context) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); - goto error; + packet_context = bt_ctf_packet_get_context(packet); + if (packet_context) { + int_ret = ctf_packet_copy_context(debug_it->err, + packet, writer_stream, writer_packet); + if (int_ret < 0) { + BT_LOGE_STR("Failed to copy packet context."); + goto error; + } + BT_PUT(packet_context); } - int_ret = bt_ctf_packet_set_context(writer_packet, writer_packet_context); - if (int_ret) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); - goto error; - } + bt_get(writer_packet); goto end; error: end: - bt_put(writer_packet_context); + bt_put(packet_context); bt_put(writer_stream); bt_put(stream); return writer_packet; @@ -1087,33 +1326,133 @@ struct bt_ctf_packet *debug_info_close_packet( struct bt_ctf_packet *packet) { struct bt_ctf_packet *writer_packet = NULL; + struct bt_ctf_stream *stream = NULL; + struct debug_info_trace *di_trace; - writer_packet = lookup_packet(debug_it, packet); + stream = bt_ctf_packet_get_stream(packet); + assert(stream); + + di_trace = lookup_di_trace_from_stream(debug_it, stream); + if (!di_trace) { + BT_LOGE_STR("Failed to find trace from stream."); + goto end; + } + + writer_packet = lookup_packet(debug_it, packet, di_trace); if (!writer_packet) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to find existing packet."); goto end; } - g_hash_table_remove(debug_it->packet_map, packet); + bt_get(writer_packet); + g_hash_table_remove(di_trace->packet_map, packet); end: + bt_put(stream); return writer_packet; } +BT_HIDDEN +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 = NULL; + enum debug_info_stream_state *state; + struct debug_info_trace *di_trace = NULL; + + di_trace = lookup_di_trace_from_stream(debug_it, stream); + if (!di_trace) { + di_trace = insert_new_trace(debug_it, stream); + if (!di_trace) { + BT_LOGE_STR("Failed to insert new trace."); + goto error; + } + } + + /* Set the stream as active */ + state = g_hash_table_lookup(di_trace->stream_states, stream); + if (!state) { + if (di_trace->trace_static) { + BT_LOGE_STR("Failed to add a new stream, trace is static."); + goto error; + } + state = insert_new_stream_state(debug_it, di_trace, + stream); + if (!state) { + BT_LOGE_STR("Failed to add new stream state."); + goto error; + } + } + if (*state != DEBUG_INFO_UNKNOWN_STREAM) { + BT_LOGE("Unexpected stream state: state=%d", *state); + goto error; + } + *state = DEBUG_INFO_ACTIVE_STREAM; + + 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; + +error: + BT_PUT(writer_stream); +end: + return writer_stream; +} + BT_HIDDEN struct bt_ctf_stream *debug_info_stream_end(struct debug_info_iterator *debug_it, struct bt_ctf_stream *stream) { - struct bt_ctf_stream *writer_stream; + struct bt_ctf_stream *writer_stream = NULL; + struct debug_info_trace *di_trace = NULL; + enum debug_info_stream_state *state; + + di_trace = lookup_di_trace_from_stream(debug_it, stream); + if (!di_trace) { + BT_LOGE_STR("Failed to find existing trace from stream."); + goto error; + } - writer_stream = lookup_stream(debug_it, stream); + 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 end; + BT_LOGE_STR("Failed to find existing stream."); + goto error; } + /* + * Take the ref on the stream and keep it until the notification + * is created. + */ bt_get(writer_stream); - g_hash_table_remove(debug_it->stream_map, stream); + + state = g_hash_table_lookup(di_trace->stream_states, stream); + if (*state != DEBUG_INFO_ACTIVE_STREAM) { + BT_LOGE("Unexpected stream state: state=%d", *state); + goto error; + } + *state = DEBUG_INFO_COMPLETED_STREAM; + + g_hash_table_remove(di_trace->stream_map, stream); + + if (di_trace->trace_static) { + int trace_completed = 1; + + g_hash_table_foreach(di_trace->stream_states, + check_completed_trace, &trace_completed); + if (trace_completed) { + debug_info_close_trace(debug_it, di_trace); + g_hash_table_remove(debug_it->trace_map, + di_trace->trace); + } + } + + goto end; + +error: + BT_PUT(writer_stream); end: return writer_stream; @@ -1153,17 +1492,13 @@ int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field, struct debug_info_source *dbg_info_src, struct debug_info_component *component) { - int i, nr_fields, ret; + int i, nr_fields, ret = 0; struct bt_ctf_field_type *debug_field_type = NULL; struct bt_ctf_field *field = NULL; struct bt_ctf_field_type *field_type = NULL; debug_field_type = bt_ctf_field_get_type(debug_field); - if (!debug_field_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(debug_field_type); nr_fields = bt_ctf_field_type_structure_get_field_count(debug_field_type); for (i = 0; i < nr_fields; i++) { @@ -1171,8 +1506,8 @@ int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field, if (bt_ctf_field_type_structure_get_field(debug_field_type, &field_name, &field_type, i) < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get field from debug_info struct: field-name=\"%s\"", + field_name); goto error; } BT_PUT(field_type); @@ -1224,8 +1559,8 @@ int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field, } BT_PUT(field); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to set value in debug-info struct: field-name=\"%s\"", + field_name); goto error; } } @@ -1249,7 +1584,8 @@ int copy_set_debug_info_stream_event_context(FILE *err, struct debug_info *debug_info, struct debug_info_component *component) { - struct bt_ctf_field_type *writer_event_context_type = NULL; + struct bt_ctf_field_type *writer_event_context_type = NULL, + *event_context_type = NULL; struct bt_ctf_field *writer_event_context = NULL; struct bt_ctf_field *field = NULL, *copy_field = NULL, *debug_field = NULL; struct bt_ctf_field_type *field_type = NULL; @@ -1257,17 +1593,13 @@ int copy_set_debug_info_stream_event_context(FILE *err, int ret, nr_fields, i; writer_event_context = bt_ctf_event_get_stream_event_context(writer_event); - if (!writer_event_context) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); - goto error; - } + assert(writer_event_context); writer_event_context_type = bt_ctf_field_get_type(writer_event_context); - if (!writer_event_context_type) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(writer_event_context_type); + + event_context_type = bt_ctf_field_get_type(event_context); + assert(event_context_type); /* * If it is not a structure, we did not modify it to add the debug info @@ -1286,48 +1618,48 @@ int copy_set_debug_info_stream_event_context(FILE *err, if (bt_ctf_field_type_structure_get_field(writer_event_context_type, &field_name, &field_type, i) < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to get field from event-context: field-name=\"%s\"", + field_name); goto error; } - field = bt_ctf_field_structure_get_field_by_index(event_context, i); + /* + * Prevent illegal access in the event_context. + */ + if (i < bt_ctf_field_type_structure_get_field_count(event_context_type)) { + field = bt_ctf_field_structure_get_field_by_index(event_context, i); + } /* * The debug_info field, only exists in the writer event or * if it was set by a earlier pass of the debug_info plugin. - * - * FIXME: are we replacing an exisiting debug_info struct here ?? */ if (!strcmp(field_name, component->arg_debug_info_field_name) && !field) { debug_field = bt_ctf_field_structure_get_field_by_index( writer_event_context, i); - if (!debug_field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(debug_field); + ret = set_debug_info_field(err, debug_field, dbg_info_src, component); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to set debug_info field."); goto error; } BT_PUT(debug_field); } else { copy_field = bt_ctf_field_copy(field); if (!copy_field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to copy field: field-name=\"%s\"", + field_name); goto error; } - ret = bt_ctf_field_structure_set_field(writer_event_context, + ret = bt_ctf_field_structure_set_field_by_name( + writer_event_context, field_name, copy_field); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE("Failed to set field: field-name=\"%s\"", + field_name); goto error; } BT_PUT(copy_field); @@ -1342,6 +1674,7 @@ int copy_set_debug_info_stream_event_context(FILE *err, error: ret = -1; end: + bt_put(event_context_type); bt_put(writer_event_context_type); bt_put(writer_event_context); bt_put(field); @@ -1359,9 +1692,10 @@ struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err, struct bt_ctf_clock_class *clock_class = NULL; trace = bt_ctf_stream_class_get_trace(stream_class); - if (!trace) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + assert(trace); + + if (!bt_ctf_trace_get_clock_class_count(trace)) { + /* No clock. */ goto end; } @@ -1382,24 +1716,14 @@ struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event struct bt_ctf_clock_class *clock_class = NULL; event_class = bt_ctf_event_get_class(event); - if (!event_class) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; - } + assert(event_class); stream_class = bt_ctf_event_class_get_stream_class(event_class); - if (!stream_class) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; - } + assert(stream_class); clock_class = stream_class_get_clock_class(err, stream_class); goto end; -error: - BT_PUT(clock_class); end: bt_put(stream_class); bt_put(event_class); @@ -1412,20 +1736,18 @@ int set_event_clock_value(FILE *err, struct bt_ctf_event *event, { struct bt_ctf_clock_class *clock_class = NULL; struct bt_ctf_clock_value *clock_value = NULL; - int ret; + int ret = 0; clock_class = event_get_clock_class(err, event); if (!clock_class) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; + /* No clock on input trace. */ + goto end; } clock_value = bt_ctf_event_get_clock_value(event, clock_class); if (!clock_value) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); - goto error; + ret = 0; + goto end; } /* @@ -1434,8 +1756,7 @@ int set_event_clock_value(FILE *err, struct bt_ctf_event *event, */ ret = bt_ctf_event_set_clock_value(writer_event, clock_value); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to set clock value."); goto error; } @@ -1462,15 +1783,13 @@ struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event writer_event = bt_ctf_event_create(writer_event_class); if (!writer_event) { - fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, - __LINE__); + BT_LOGE_STR("Failed to create new event."); goto error; } ret = set_event_clock_value(err, event, writer_event); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to set clock value."); goto error; } @@ -1480,8 +1799,7 @@ struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event ret = ctf_copy_event_header(err, event, writer_event_class, writer_event, field); if (ret) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to copy event header."); goto error; } BT_PUT(field); @@ -1494,8 +1812,7 @@ struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event field, event, writer_event, debug_info, component); if (ret < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to debug_info stream event context."); goto error; } BT_PUT(field); @@ -1506,14 +1823,12 @@ struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event if (field) { copy_field = bt_ctf_field_copy(field); if (!copy_field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to copy field."); goto error; } ret = bt_ctf_event_set_event_context(writer_event, copy_field); if (ret < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to set event_context."); goto error; } BT_PUT(copy_field); @@ -1521,17 +1836,13 @@ struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event } field = bt_ctf_event_get_event_payload(event); - if (!field) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(field); + copy_field = bt_ctf_field_copy(field); if (copy_field) { ret = bt_ctf_event_set_event_payload(writer_event, copy_field); if (ret < 0) { - fprintf(err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to set event payload."); goto error; } BT_PUT(copy_field); @@ -1558,39 +1869,34 @@ struct bt_ctf_event *debug_info_output_event( struct bt_ctf_event *writer_event = NULL; struct bt_ctf_packet *packet = NULL, *writer_packet = NULL; struct bt_ctf_trace *writer_trace = NULL; + struct bt_ctf_stream *stream = NULL; + struct debug_info_trace *di_trace; struct debug_info *debug_info; - const char *event_name; int int_ret; event_class = bt_ctf_event_get_class(event); - if (!event_class) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } - - event_name = bt_ctf_event_class_get_name(event_class); - if (!event_name) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(event_class); stream_class = bt_ctf_event_class_get_stream_class(event_class); - if (!stream_class) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + assert(stream_class); + + stream = bt_ctf_event_get_stream(event); + assert(stream); + + di_trace = lookup_di_trace_from_stream(debug_it, stream); + if (!di_trace) { + BT_LOGE_STR("Failed to find existing trace from stream."); goto error; } writer_stream_class = g_hash_table_lookup( - debug_it->stream_class_map, + di_trace->stream_class_map, (gpointer) stream_class); - if (!writer_stream_class || !bt_get(writer_stream_class)) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + if (!writer_stream_class) { + BT_LOGE_STR("Failed to find existing stream_class."); goto error; } + bt_get(writer_stream_class); writer_event_class = get_event_class(debug_it, writer_stream_class, event_class); @@ -1598,27 +1904,21 @@ struct bt_ctf_event *debug_info_output_event( writer_event_class = ctf_copy_event_class(debug_it->err, event_class); if (!writer_event_class) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to copy event_class."); goto error; } int_ret = bt_ctf_stream_class_add_event_class( writer_stream_class, writer_event_class); if (int_ret) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", - __func__, __FILE__, __LINE__); + BT_LOGE_STR("Failed to add event_class."); goto error; } } writer_trace = bt_ctf_stream_class_get_trace(writer_stream_class); - if (!writer_trace) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(writer_trace); - debug_info = get_trace_debug_info(debug_it, writer_trace); + debug_info = get_trace_debug_info(debug_it, writer_trace, di_trace); if (debug_info) { debug_info_handle_event(debug_it->err, event, debug_info); } @@ -1627,33 +1927,24 @@ struct bt_ctf_event *debug_info_output_event( writer_event_class, debug_info, debug_it->debug_info_component); if (!writer_event) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - fprintf(debug_it->err, "[error] Failed to copy event %s\n", + BT_LOGE("Failed to copy event: event-class-name=\"%s\"", bt_ctf_event_class_get_name(writer_event_class)); goto error; } packet = bt_ctf_event_get_packet(event); - if (!packet) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - goto error; - } + assert(packet); - writer_packet = lookup_packet(debug_it, packet); + writer_packet = lookup_packet(debug_it, packet, di_trace); if (!writer_packet) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); + BT_LOGE_STR("Failed to find existing packet."); goto error; } bt_get(writer_packet); int_ret = bt_ctf_event_set_packet(writer_event, writer_packet); if (int_ret < 0) { - fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__, - __FILE__, __LINE__); - fprintf(debug_it->err, "[error] Failed to append event %s\n", + BT_LOGE("Failed to append event to event-class-name=\"%s\"", bt_ctf_event_class_get_name(writer_event_class)); goto error; } @@ -1665,6 +1956,7 @@ error: BT_PUT(writer_event); end: + bt_put(stream); bt_put(writer_trace); bt_put(writer_packet); bt_put(packet);