From 1a6da3f9c9a9377973679ca269cd81079d834044 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Tue, 9 Jul 2019 20:18:43 -0400 Subject: [PATCH] ctf: add internal ctf_metadata_decoder_get_trace_class_uuid() This new internal function gets the trace class's UUID from the AST, without having to create trace IR and CTF IR trace classes, which is a much slower process (many allocations and checks). Signed-off-by: Philippe Proulx Change-Id: I04d58c66a461219ca01bf120417d629d9a1b9d10 Reviewed-on: https://review.lttng.org/c/babeltrace/+/1843 CI-Build: Simon Marchi Tested-by: jenkins --- src/plugins/ctf/common/metadata/ast.h | 91 +++++++++++++ src/plugins/ctf/common/metadata/decoder.c | 77 +++++++++++ src/plugins/ctf/common/metadata/decoder.h | 18 ++- .../ctf/common/metadata/visitor-generate-ir.c | 120 +++--------------- src/plugins/ctf/lttng-live/metadata.c | 4 +- 5 files changed, 204 insertions(+), 106 deletions(-) diff --git a/src/plugins/ctf/common/metadata/ast.h b/src/plugins/ctf/common/metadata/ast.h index 6b305e53..b0221d63 100644 --- a/src/plugins/ctf/common/metadata/ast.h +++ b/src/plugins/ctf/common/metadata/ast.h @@ -23,6 +23,7 @@ #include "common/list.h" #include #include "common/macros.h" +#include "common/assert.h" #include "decoder.h" #include "ctf-meta.h" @@ -344,4 +345,94 @@ BT_HIDDEN int ctf_visitor_parent_links(int depth, struct ctf_node *node, struct meta_log_config *log_cfg); +static inline +char *ctf_ast_concatenate_unary_strings(struct bt_list_head *head) +{ + int i = 0; + GString *str; + struct ctf_node *node; + + str = g_string_new(NULL); + BT_ASSERT(str); + + bt_list_for_each_entry(node, head, siblings) { + char *src_string; + + if ( + node->type != NODE_UNARY_EXPRESSION || + node->u.unary_expression.type != UNARY_STRING || + !( + ( + node->u.unary_expression.link != + UNARY_LINK_UNKNOWN + ) ^ (i == 0) + ) + ) { + goto error; + } + + switch (node->u.unary_expression.link) { + case UNARY_DOTLINK: + g_string_append(str, "."); + break; + case UNARY_ARROWLINK: + g_string_append(str, "->"); + break; + case UNARY_DOTDOTDOT: + g_string_append(str, "..."); + break; + default: + break; + } + + src_string = node->u.unary_expression.u.string; + g_string_append(str, src_string); + i++; + } + + /* Destroys the container, returns the underlying string */ + return g_string_free(str, FALSE); + +error: + /* This always returns NULL */ + return g_string_free(str, TRUE); +} + +static inline +int ctf_ast_get_unary_uuid(struct bt_list_head *head, + bt_uuid_t uuid, int log_level, bt_self_component *self_comp) +{ + int i = 0; + int ret = 0; + struct ctf_node *node; + + bt_list_for_each_entry(node, head, siblings) { + int uexpr_type = node->u.unary_expression.type; + int uexpr_link = node->u.unary_expression.link; + const char *src_string; + + if (node->type != NODE_UNARY_EXPRESSION || + uexpr_type != UNARY_STRING || + uexpr_link != UNARY_LINK_UNKNOWN || + i != 0) { + ret = -EINVAL; + goto end; + } + + src_string = node->u.unary_expression.u.string; + ret = bt_uuid_from_str(src_string, uuid); + if (ret) { +#ifdef BT_COMP_LOG_CUR_LVL + BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, + self_comp, + "Cannot parse UUID: uuid=\"%s\"", src_string); +#endif + goto end; + } + } + +end: + return ret; +} + #endif /* _CTF_AST_H */ diff --git a/src/plugins/ctf/common/metadata/decoder.c b/src/plugins/ctf/common/metadata/decoder.c index 17b2aa4b..7407ad33 100644 --- a/src/plugins/ctf/common/metadata/decoder.c +++ b/src/plugins/ctf/common/metadata/decoder.c @@ -406,3 +406,80 @@ int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec, end: return ret; } + +static +enum ctf_metadata_decoder_status find_uuid_in_trace_decl( + struct ctf_metadata_decoder *mdec, struct ctf_node *trace_node, + bt_uuid_t uuid) +{ + enum ctf_metadata_decoder_status status = + CTF_METADATA_DECODER_STATUS_OK; + struct ctf_node *entry_node; + struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list; + char *left = NULL; + + bt_list_for_each_entry(entry_node, decl_list, siblings) { + if (entry_node->type == NODE_CTF_EXPRESSION) { + int ret; + + left = ctf_ast_concatenate_unary_strings( + &entry_node->u.ctf_expression.left); + if (!left) { + BT_COMP_LOGE("Cannot concatenate unary strings."); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + if (strcmp(left, "uuid") == 0) { + ret = ctf_ast_get_unary_uuid( + &entry_node->u.ctf_expression.right, + uuid, mdec->config.log_level, + mdec->config.self_comp); + if (ret) { + BT_COMP_LOGE("Invalid trace's `uuid` attribute."); + status = CTF_METADATA_DECODER_STATUS_ERROR; + goto end; + } + + goto end; + } + + g_free(left); + left = NULL; + } + } + + status = CTF_METADATA_DECODER_STATUS_NONE; + +end: + g_free(left); + return status; +} + +BT_HIDDEN +enum ctf_metadata_decoder_status ctf_metadata_decoder_get_trace_class_uuid( + struct ctf_metadata_decoder *mdec, bt_uuid_t uuid) +{ + enum ctf_metadata_decoder_status status = + CTF_METADATA_DECODER_STATUS_INCOMPLETE; + struct ctf_node *root_node = &mdec->scanner->ast->root; + struct ctf_node *trace_node; + + if (!root_node) { + status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + goto end; + } + + trace_node = + bt_list_entry(root_node->u.root.trace.next, + struct ctf_node, siblings); + if (!trace_node) { + status = CTF_METADATA_DECODER_STATUS_INCOMPLETE; + goto end; + } + + status = find_uuid_in_trace_decl(mdec, trace_node, uuid); + +end: + return status; +} diff --git a/src/plugins/ctf/common/metadata/decoder.h b/src/plugins/ctf/common/metadata/decoder.h index f6754899..d94128e1 100644 --- a/src/plugins/ctf/common/metadata/decoder.h +++ b/src/plugins/ctf/common/metadata/decoder.h @@ -31,6 +31,7 @@ struct ctf_metadata_decoder; /* CTF metadata decoder status */ enum ctf_metadata_decoder_status { CTF_METADATA_DECODER_STATUS_OK = 0, + CTF_METADATA_DECODER_STATUS_NONE = 1, CTF_METADATA_DECODER_STATUS_ERROR = -1, CTF_METADATA_DECODER_STATUS_INCOMPLETE = -2, CTF_METADATA_DECODER_STATUS_INVAL_VERSION = -3, @@ -148,12 +149,23 @@ int ctf_metadata_decoder_get_byte_order(struct ctf_metadata_decoder *mdec); /* * Returns the UUID of the decoder's metadata stream as set by the last * call to ctf_metadata_decoder_append_content(). + */ +BT_HIDDEN +int ctf_metadata_decoder_get_uuid( + struct ctf_metadata_decoder *mdec, bt_uuid_t uuid); + +/* + * Returns the UUID of the decoder's trace class, if available. * - * Returns -1 if unknown (plain text content). + * Returns: + * + * * `CTF_METADATA_DECODER_STATUS_OK`: success. + * * `CTF_METADATA_DECODER_STATUS_NONE`: no UUID. + * * `CTF_METADATA_DECODER_STATUS_INCOMPLETE`: missing metadata content. */ BT_HIDDEN -int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec, - bt_uuid_t uuid); +enum ctf_metadata_decoder_status ctf_metadata_decoder_get_trace_class_uuid( + struct ctf_metadata_decoder *mdec, bt_uuid_t uuid); /* * Returns the metadata decoder's current metadata text. diff --git a/src/plugins/ctf/common/metadata/visitor-generate-ir.c b/src/plugins/ctf/common/metadata/visitor-generate-ir.c index 7bad5266..f2ac4950 100644 --- a/src/plugins/ctf/common/metadata/visitor-generate-ir.c +++ b/src/plugins/ctf/common/metadata/visitor-generate-ir.c @@ -698,59 +698,6 @@ int is_unary_string(struct bt_list_head *head) return ret; } -static -char *concatenate_unary_strings(struct bt_list_head *head) -{ - int i = 0; - GString *str; - struct ctf_node *node; - - str = g_string_new(NULL); - BT_ASSERT(str); - - bt_list_for_each_entry(node, head, siblings) { - char *src_string; - - if ( - node->type != NODE_UNARY_EXPRESSION || - node->u.unary_expression.type != UNARY_STRING || - !( - ( - node->u.unary_expression.link != - UNARY_LINK_UNKNOWN - ) ^ (i == 0) - ) - ) { - goto error; - } - - switch (node->u.unary_expression.link) { - case UNARY_DOTLINK: - g_string_append(str, "."); - break; - case UNARY_ARROWLINK: - g_string_append(str, "->"); - break; - case UNARY_DOTDOTDOT: - g_string_append(str, "..."); - break; - default: - break; - } - - src_string = node->u.unary_expression.u.string; - g_string_append(str, src_string); - i++; - } - - /* Destroys the container, returns the underlying string */ - return g_string_free(str, FALSE); - -error: - /* This always returns NULL */ - return g_string_free(str, TRUE); -} - static const char *get_map_clock_name_value(struct bt_list_head *head) { @@ -922,38 +869,11 @@ end: return ret; } -static int get_unary_uuid(struct ctx *ctx, struct bt_list_head *head, - uint8_t *uuid) + bt_uuid_t uuid) { - int i = 0; - int ret = 0; - struct ctf_node *node; - - bt_list_for_each_entry(node, head, siblings) { - int uexpr_type = node->u.unary_expression.type; - int uexpr_link = node->u.unary_expression.link; - const char *src_string; - - if (node->type != NODE_UNARY_EXPRESSION || - uexpr_type != UNARY_STRING || - uexpr_link != UNARY_LINK_UNKNOWN || - i != 0) { - ret = -EINVAL; - goto end; - } - - src_string = node->u.unary_expression.u.string; - ret = bt_uuid_from_str(src_string, uuid); - if (ret) { - _BT_COMP_LOGE_NODE(node, - "Cannot parse UUID: uuid=\"%s\"", src_string); - goto end; - } - } - -end: - return ret; + return ctf_ast_get_unary_uuid(head, uuid, ctx->log_cfg.log_level, + ctx->log_cfg.self_comp); } static @@ -1381,7 +1301,7 @@ int visit_field_class_declarator(struct ctx *ctx, { /* Lookup unsigned integer definition, create seq. */ struct ctf_field_class_sequence *seq_decl = NULL; - char *length_name = concatenate_unary_strings(length); + char *length_name = ctf_ast_concatenate_unary_strings(length); if (!length_name) { _BT_COMP_LOGE_NODE(node_field_class_declarator, @@ -2445,7 +2365,7 @@ int visit_integer_decl(struct ctx *ctx, } case UNARY_STRING: { - char *s_right = concatenate_unary_strings( + char *s_right = ctf_ast_concatenate_unary_strings( &expression->u.ctf_expression.right); if (!s_right) { _BT_COMP_LOGE_NODE(right, @@ -2512,7 +2432,7 @@ int visit_integer_decl(struct ctx *ctx, goto error; } - s_right = concatenate_unary_strings( + s_right = ctf_ast_concatenate_unary_strings( &expression->u.ctf_expression.right); if (!s_right) { _BT_COMP_LOGE_NODE(right, @@ -2564,7 +2484,7 @@ int visit_integer_decl(struct ctx *ctx, get_map_clock_name_value( &expression->u.ctf_expression.right); if (!clock_name) { - char *s_right = concatenate_unary_strings( + char *s_right = ctf_ast_concatenate_unary_strings( &expression->u.ctf_expression.right); if (!s_right) { @@ -2868,7 +2788,7 @@ int visit_string_decl(struct ctx *ctx, goto error; } - s_right = concatenate_unary_strings( + s_right = ctf_ast_concatenate_unary_strings( &expression->u.ctf_expression.right); if (!s_right) { _BT_COMP_LOGE_NODE(right, @@ -3068,7 +2988,7 @@ int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node, break; case NODE_CTF_EXPRESSION: { - left = concatenate_unary_strings(&node->u.ctf_expression.left); + left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); if (!left) { _BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings."); ret = -EINVAL; @@ -3259,7 +3179,7 @@ int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node, goto error; } - right = concatenate_unary_strings( + right = ctf_ast_concatenate_unary_strings( &node->u.ctf_expression.right); if (!right) { _BT_COMP_LOGE_NODE(node, @@ -3315,7 +3235,7 @@ char *get_event_decl_name(struct ctx *ctx, struct ctf_node *node) continue; } - left = concatenate_unary_strings(&iter->u.ctf_expression.left); + left = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.left); if (!left) { _BT_COMP_LOGE_NODE(iter, "Cannot concatenate unary strings."); @@ -3323,7 +3243,7 @@ char *get_event_decl_name(struct ctx *ctx, struct ctf_node *node) } if (strcmp(left, "name") == 0) { - name = concatenate_unary_strings( + name = ctf_ast_concatenate_unary_strings( &iter->u.ctf_expression.right); if (!name) { _BT_COMP_LOGE_NODE(iter, @@ -3628,7 +3548,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, break; case NODE_CTF_EXPRESSION: { - left = concatenate_unary_strings(&node->u.ctf_expression.left); + left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); if (!left) { _BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings."); ret = -EINVAL; @@ -3904,7 +3824,7 @@ int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set) break; case NODE_CTF_EXPRESSION: { - left = concatenate_unary_strings(&node->u.ctf_expression.left); + left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left); if (!left) { _BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings."); ret = -EINVAL; @@ -4122,7 +4042,7 @@ int visit_env(struct ctx *ctx, struct ctf_node *node) goto error; } - left = concatenate_unary_strings( + left = ctf_ast_concatenate_unary_strings( &entry_node->u.ctf_expression.left); if (!left) { _BT_COMP_LOGE_NODE(entry_node, @@ -4132,7 +4052,7 @@ int visit_env(struct ctx *ctx, struct ctf_node *node) } if (is_unary_string(right_head)) { - char *right = concatenate_unary_strings(right_head); + char *right = ctf_ast_concatenate_unary_strings(right_head); if (!right) { _BT_COMP_LOGE_NODE(entry_node, @@ -4207,7 +4127,7 @@ int set_trace_byte_order(struct ctx *ctx, struct ctf_node *trace_node) if (node->type == NODE_CTF_EXPRESSION) { struct ctf_node *right_node; - left = concatenate_unary_strings( + left = ctf_ast_concatenate_unary_strings( &node->u.ctf_expression.left); if (!left) { _BT_COMP_LOGE_NODE(node, @@ -4284,7 +4204,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - left = concatenate_unary_strings(&entry_node->u.ctf_expression.left); + left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left); if (!left) { _BT_COMP_LOGE_NODE(entry_node, "Cannot concatenate unary strings."); ret = -EINVAL; @@ -4300,7 +4220,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - right = concatenate_unary_strings( + right = ctf_ast_concatenate_unary_strings( &entry_node->u.ctf_expression.right); if (!right) { _BT_COMP_LOGE_NODE(entry_node, @@ -4342,7 +4262,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - right = concatenate_unary_strings( + right = ctf_ast_concatenate_unary_strings( &entry_node->u.ctf_expression.right); if (!right) { _BT_COMP_LOGE_NODE(entry_node, diff --git a/src/plugins/ctf/lttng-live/metadata.c b/src/plugins/ctf/lttng-live/metadata.c index 61227141..0061565e 100644 --- a/src/plugins/ctf/lttng-live/metadata.c +++ b/src/plugins/ctf/lttng-live/metadata.c @@ -255,9 +255,7 @@ enum lttng_live_iterator_status lttng_live_metadata_update( case CTF_METADATA_DECODER_STATUS_INCOMPLETE: status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN; break; - case CTF_METADATA_DECODER_STATUS_ERROR: - case CTF_METADATA_DECODER_STATUS_INVAL_VERSION: - case CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR: + default: goto error; } -- 2.34.1