Fix: use of uninitialized value in visit_*_decl_entry
[babeltrace.git] / plugins / ctf / common / metadata / visitor-generate-ir.c
index e3ca366fba4e26c5dca8cdca1329cb1747b12a97..badbf995bacaecbd99a97857a252372ca706cad3 100644 (file)
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <assert.h>
 #include <glib.h>
 #include <inttypes.h>
 #include <errno.h>
-#include <babeltrace/compat/uuid.h>
-#include <babeltrace/endian.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/endian-internal.h>
 #include <babeltrace/ref.h>
 #include <babeltrace/ctf-ir/trace.h>
 #include <babeltrace/ctf-ir/stream-class.h>
@@ -219,6 +220,9 @@ struct ctx {
        /* 1 if trace declaration is visited */
        int is_trace_visited;
 
+       /* 1 if this is an LTTng trace */
+       bool is_lttng;
+
        /* Offset (ns) to apply to clock classes on creation */
        uint64_t clock_class_offset_ns;
 
@@ -1041,7 +1045,7 @@ enum bt_ctf_byte_order get_real_byte_order(struct ctx *ctx,
        enum bt_ctf_byte_order bo = byte_order_from_unary_expr(ctx->efd, uexpr);
 
        if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
-               bo = bt_ctf_trace_get_byte_order(ctx->trace);
+               bo = bt_ctf_trace_get_native_byte_order(ctx->trace);
        }
 
        return bo;
@@ -1169,7 +1173,7 @@ static
 int get_type_specifier_list_name(struct ctx *ctx,
        struct ctf_node *type_specifier_list, GString *str)
 {
-       int ret;
+       int ret = 0;
        struct ctf_node *iter;
        int alias_item_nr = 0;
        struct bt_list_head *head =
@@ -1288,7 +1292,7 @@ int visit_type_declarator(struct ctx *ctx, struct ctf_node *type_specifier_list,
                        nested_decl_copy = bt_ctf_field_type_copy(nested_decl);
                        BT_PUT(nested_decl);
                        if (!nested_decl_copy) {
-                               _PERROR("%s", "cannot copy nested declaration");
+                               _PERROR("%s", "cannot copy nested field type");
                                ret = -EINVAL;
                                goto error;
                        }
@@ -1363,7 +1367,7 @@ int visit_type_declarator(struct ctx *ctx, struct ctf_node *type_specifier_list,
                        BT_PUT(nested_decl);
                        if (!array_decl) {
                                _PERROR("%s",
-                                       "cannot create array declaration");
+                                       "cannot create array field type");
                                ret = -ENOMEM;
                                goto error;
                        }
@@ -1388,7 +1392,7 @@ int visit_type_declarator(struct ctx *ctx, struct ctf_node *type_specifier_list,
                        BT_PUT(nested_decl);
                        if (!seq_decl) {
                                _PERROR("%s",
-                                       "cannot create sequence declaration");
+                                       "cannot create sequence field type");
                                ret = -ENOMEM;
                                goto error;
                        }
@@ -1461,7 +1465,7 @@ int visit_struct_decl_field(struct ctx *ctx,
                        &qfield_name, iter, &field_decl, NULL);
                if (ret) {
                        assert(!field_decl);
-                       _PERROR("%s", "unable to find structure field declaration type");
+                       _PERROR("%s", "cannot visit type declarator");
                        goto error;
                }
 
@@ -1520,7 +1524,7 @@ int visit_variant_decl_field(struct ctx *ctx,
                if (ret) {
                        assert(!field_decl);
                        _PERROR("%s",
-                               "unable to find variant field declaration type");
+                               "cannot visit type declarator");
                        goto error;
                }
 
@@ -1571,7 +1575,7 @@ int visit_typedef(struct ctx *ctx, struct ctf_node *type_specifier_list,
                ret = visit_type_declarator(ctx, type_specifier_list,
                        &qidentifier, iter, &type_decl, NULL);
                if (ret) {
-                       _PERROR("%s", "problem creating type declaration");
+                       _PERROR("%s", "cannot visit type declarator");
                        ret = -EINVAL;
                        goto end;
                }
@@ -1624,7 +1628,7 @@ int visit_typealias(struct ctx *ctx, struct ctf_node *target,
                &qdummy_field_name, node, &type_decl, NULL);
        if (ret) {
                assert(!type_decl);
-               _PERROR("%s", "problem creating type declaration");
+               _PERROR("%s", "cannot visit type declarator");
                goto end;
        }
 
@@ -1792,7 +1796,7 @@ int visit_struct_decl(struct ctx *ctx, const char *name,
                struct_decl_copy = bt_ctf_field_type_copy(*struct_decl);
                if (!struct_decl_copy) {
                        _PERROR("%s",
-                               "cannot create copy of structure declaration");
+                               "cannot create copy of structure field type");
                        ret = -EINVAL;
                        goto error;
                }
@@ -1826,7 +1830,7 @@ int visit_struct_decl(struct ctx *ctx, const char *name,
 
                *struct_decl = bt_ctf_field_type_structure_create();
                if (!*struct_decl) {
-                       _PERROR("%s", "cannot create structure declaration");
+                       _PERROR("%s", "cannot create structure field type");
                        ret = -ENOMEM;
                        goto error;
                }
@@ -1909,7 +1913,7 @@ int visit_variant_decl(struct ctx *ctx, const char *name,
                        untagged_variant_decl);
                if (!variant_decl_copy) {
                        _PERROR("%s",
-                               "cannot create copy of structure declaration");
+                               "cannot create copy of variant field type");
                        ret = -EINVAL;
                        goto error;
                }
@@ -1935,7 +1939,7 @@ int visit_variant_decl(struct ctx *ctx, const char *name,
                untagged_variant_decl = bt_ctf_field_type_variant_create(NULL,
                        NULL);
                if (!untagged_variant_decl) {
-                       _PERROR("%s", "cannot create variant declaration");
+                       _PERROR("%s", "cannot create variant field type");
                        ret = -ENOMEM;
                        goto error;
                }
@@ -2116,7 +2120,7 @@ int visit_enum_decl(struct ctx *ctx, const char *name,
                enum_decl_copy = bt_ctf_field_type_copy(*enum_decl);
                if (!enum_decl_copy) {
                        _PERROR("%s",
-                               "cannot create copy of enumeration declaration");
+                               "cannot create copy of enumeration field type");
                        ret = -EINVAL;
                        goto error;
                }
@@ -2169,7 +2173,7 @@ int visit_enum_decl(struct ctx *ctx, const char *name,
 
                *enum_decl = bt_ctf_field_type_enumeration_create(integer_decl);
                if (!*enum_decl) {
-                       _PERROR("%s", "cannot create enumeration declaration");
+                       _PERROR("%s", "cannot create enumeration field type");
                        ret = -ENOMEM;
                        goto error;
                }
@@ -2229,7 +2233,7 @@ int visit_type_specifier(struct ctx *ctx,
        /* Make a copy of the type declaration */
        decl_copy = bt_ctf_field_type_copy(*decl);
        if (!decl_copy) {
-               _PERROR("%s", "cannot create copy of type declaration");
+               _PERROR("%s", "cannot create field type copy");
                ret = -EINVAL;
                goto error;
        }
@@ -2264,7 +2268,7 @@ int visit_integer_decl(struct ctx *ctx,
        enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_NONE;
        enum bt_ctf_integer_base base = BT_CTF_INTEGER_BASE_DECIMAL;
        enum bt_ctf_byte_order byte_order =
-               bt_ctf_trace_get_byte_order(ctx->trace);
+               bt_ctf_trace_get_native_byte_order(ctx->trace);
 
        *integer_decl = NULL;
 
@@ -2562,7 +2566,7 @@ int visit_integer_decl(struct ctx *ctx,
 
        *integer_decl = bt_ctf_field_type_integer_create((unsigned int) size);
        if (!*integer_decl) {
-               _PERROR("%s", "cannot create integer declaration");
+               _PERROR("%s", "cannot create integer field type");
                ret = -ENOMEM;
                goto error;
        }
@@ -2583,7 +2587,7 @@ int visit_integer_decl(struct ctx *ctx,
        }
 
        if (ret) {
-               _PERROR("%s", "cannot configure integer declaration");
+               _PERROR("%s", "cannot configure integer field type");
                ret = -EINVAL;
                goto error;
        }
@@ -2610,7 +2614,7 @@ int visit_floating_point_number_decl(struct ctx *ctx,
        struct ctf_node *expression;
        uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
        enum bt_ctf_byte_order byte_order =
-               bt_ctf_trace_get_byte_order(ctx->trace);
+               bt_ctf_trace_get_native_byte_order(ctx->trace);
 
        *float_decl = NULL;
 
@@ -2738,7 +2742,7 @@ int visit_floating_point_number_decl(struct ctx *ctx,
        *float_decl = bt_ctf_field_type_floating_point_create();
        if (!*float_decl) {
                _PERROR("%s",
-                       "cannot create floating point number declaration");
+                       "cannot create floating point number field type");
                ret = -ENOMEM;
                goto error;
        }
@@ -2751,7 +2755,7 @@ int visit_floating_point_number_decl(struct ctx *ctx,
        ret |= bt_ctf_field_type_set_alignment(*float_decl, alignment);
        if (ret) {
                _PERROR("%s",
-                       "cannot configure floating point number declaration");
+                       "cannot configure floating point number field type");
                ret = -EINVAL;
                goto error;
        }
@@ -2842,14 +2846,14 @@ int visit_string_decl(struct ctx *ctx,
 
        *string_decl = bt_ctf_field_type_string_create();
        if (!*string_decl) {
-               _PERROR("%s", "cannot create string declaration");
+               _PERROR("%s", "cannot create string field type");
                ret = -ENOMEM;
                goto error;
        }
 
        ret = bt_ctf_field_type_string_set_encoding(*string_decl, encoding);
        if (ret) {
-               _PERROR("%s", "cannot configure string declaration");
+               _PERROR("%s", "cannot configure string field type");
                ret = -EINVAL;
                goto error;
        }
@@ -3033,7 +3037,8 @@ int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
 
                        ret = get_unary_unsigned(&node->u.ctf_expression.right,
                                (uint64_t *) &id);
-                       if (ret || id < 0) {
+                       /* Only read "id" if get_unary_unsigned() succeeded. */
+                       if (ret || (!ret && id < 0)) {
                                _PERROR("%s", "unexpected unary expression for event declaration's \"id\" attribute");
                                ret = -EINVAL;
                                goto error;
@@ -3057,7 +3062,11 @@ int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
 
                        ret = get_unary_unsigned(&node->u.ctf_expression.right,
                                (uint64_t *) stream_id);
-                       if (ret || *stream_id < 0) {
+                       /*
+                        * Only read "stream_id" if get_unary_unsigned()
+                        * succeeded.
+                        */
+                       if (ret || (!ret && *stream_id < 0)) {
                                _PERROR("%s", "unexpected unary expression for event declaration's \"stream_id\" attribute");
                                ret = -EINVAL;
                                goto error;
@@ -3104,7 +3113,7 @@ int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                        struct ctf_node, siblings),
                                &decl);
                        if (ret) {
-                               _PERROR("%s", "cannot create event payload declaration");
+                               _PERROR("%s", "cannot create event payload field type");
                                goto error;
                        }
 
@@ -3113,7 +3122,7 @@ int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                event_class, decl);
                        BT_PUT(decl);
                        if (ret) {
-                               _PERROR("%s", "cannot set event's payload declaration");
+                               _PERROR("%s", "cannot set event's payload field type");
                                goto error;
                        }
 
@@ -3434,8 +3443,9 @@ int visit_event_decl(struct ctx *ctx, struct ctf_node *node)
                        } else {
                                assert(bt_ctf_trace_get_stream_class_count(
                                        ctx->trace) == 1);
-                               stream_class = bt_ctf_trace_get_stream_class(
-                                       ctx->trace, 0);
+                               stream_class =
+                                       bt_ctf_trace_get_stream_class_by_index(
+                                               ctx->trace, 0);
                                assert(stream_class);
                                stream_id = bt_ctf_stream_class_get_id(
                                        stream_class);
@@ -3497,17 +3507,7 @@ int visit_event_decl(struct ctx *ctx, struct ctf_node *node)
                event_id);
        if (eevent_class) {
                BT_PUT(eevent_class);
-               _PERROR("%s", "duplicate event with ID %" PRId64 " in same stream");
-               ret = -EEXIST;
-               goto error;
-       }
-
-       eevent_class = bt_ctf_stream_class_get_event_class_by_name(stream_class,
-               event_name);
-       if (eevent_class) {
-               BT_PUT(eevent_class);
-               _PERROR("%s",
-                       "duplicate event with name \"%s\" in same stream");
+               _PERROR("duplicate event with ID %" PRId64 " in same stream", event_id);
                ret = -EEXIST;
                goto error;
        }
@@ -3580,7 +3580,8 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
 
                        ret = get_unary_unsigned(&node->u.ctf_expression.right,
                                (uint64_t *) &id);
-                       if (ret || id < 0) {
+                       /* Only read "id" if get_unary_unsigned() succeeded. */
+                       if (ret || (!ret && id < 0)) {
                                _PERROR("%s", "unexpected unary expression for stream declaration's \"id\" attribute");
                                ret = -EINVAL;
                                goto error;
@@ -3598,7 +3599,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                        ret = bt_ctf_stream_class_set_id(stream_class, id);
                        if (ret) {
                                _PERROR("%s",
-                                       "cannot set stream declaration's ID");
+                                       "cannot set stream class's ID");
                                goto error;
                        }
 
@@ -3616,7 +3617,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                        struct ctf_node, siblings),
                                &decl);
                        if (ret) {
-                               _PERROR("%s", "cannot create event header declaration");
+                               _PERROR("%s", "cannot create event header field type");
                                goto error;
                        }
 
@@ -3626,7 +3627,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                stream_class, decl);
                        BT_PUT(decl);
                        if (ret) {
-                               _PERROR("%s", "cannot set stream's event header declaration");
+                               _PERROR("%s", "cannot set stream's event header field type");
                                goto error;
                        }
 
@@ -3644,7 +3645,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                        struct ctf_node, siblings),
                                &decl);
                        if (ret) {
-                               _PERROR("%s", "cannot create stream event context declaration");
+                               _PERROR("%s", "cannot create stream event context field type");
                                goto error;
                        }
 
@@ -3654,7 +3655,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                stream_class, decl);
                        BT_PUT(decl);
                        if (ret) {
-                               _PERROR("%s", "cannot set stream's event context declaration");
+                               _PERROR("%s", "cannot set stream's event context field type");
                                goto error;
                        }
 
@@ -3672,7 +3673,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                        struct ctf_node, siblings),
                                &decl);
                        if (ret) {
-                               _PERROR("%s", "cannot create packet context declaration");
+                               _PERROR("%s", "cannot create packet context field type");
                                goto error;
                        }
 
@@ -3682,7 +3683,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
                                stream_class, decl);
                        BT_PUT(decl);
                        if (ret) {
-                               _PERROR("%s", "cannot set stream's packet context declaration");
+                               _PERROR("%s", "cannot set stream's packet context field type");
                                goto error;
                        }
 
@@ -3758,7 +3759,7 @@ int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
                        bt_ctf_trace_get_packet_header_type(ctx->trace);
                if (!packet_header_decl) {
                        _PERROR("%s",
-                               "cannot get trace packet header declaration");
+                               "cannot get trace packet header field type");
                        goto error;
                }
 
@@ -3911,6 +3912,13 @@ int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
                                goto error;
                        }
 
+                       ret = bt_ctf_trace_set_uuid(ctx->trace, ctx->trace_uuid);
+                       if (ret) {
+                               _PERROR("%s",
+                                       "cannot set trace's UUID");
+                               goto error;
+                       }
+
                        _SET(set, _TRACE_UUID_SET);
                } else if (!strcmp(left, "byte_order")) {
                        /* Native byte order is already known at this stage */
@@ -3935,7 +3943,7 @@ int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
                                        struct ctf_node, siblings),
                                &packet_header_decl);
                        if (ret) {
-                               _PERROR("%s", "cannot create packet header declaration");
+                               _PERROR("%s", "cannot create packet header field type");
                                goto error;
                        }
 
@@ -3944,7 +3952,7 @@ int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
                                packet_header_decl);
                        BT_PUT(packet_header_decl);
                        if (ret) {
-                               _PERROR("%s", "cannot set trace declaration's packet header declaration");
+                               _PERROR("%s", "cannot set trace's packet header field type");
                                goto error;
                        }
 
@@ -4079,6 +4087,12 @@ int visit_env(struct ctx *ctx, struct ctf_node *node)
                                goto error;
                        }
 
+                       if (strcmp(left, "tracer_name") == 0) {
+                               if (strncmp(right, "lttng", 5) == 0) {
+                                       ctx->is_lttng = 1;
+                               }
+                       }
+
                        printf_verbose("env.%s = \"%s\"\n", left, right);
                        ret = bt_ctf_trace_set_environment_field_string(
                                ctx->trace, left, right);
@@ -4488,6 +4502,7 @@ int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
        struct bt_ctf_clock_class *clock;
        struct ctf_node *entry_node;
        struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
+       const char *clock_class_name;
 
        if (clock_node->visited) {
                return 0;
@@ -4515,10 +4530,20 @@ int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
                goto error;
        }
 
-       if (bt_ctf_trace_get_clock_class_count(ctx->trace) != 0) {
-               _PERROR("%s", "only CTF traces with a single clock class declaration are supported as of this version");
-               ret = -EINVAL;
-               goto error;
+       clock_class_name = bt_ctf_clock_class_get_name(clock);
+       assert(clock_class_name);
+       if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
+               /*
+                * Old versions of LTTng forgot to set its clock class
+                * as absolute, even if it is. This is important because
+                * it's a condition to be able to sort notifications
+                * from different sources.
+                */
+               ret = bt_ctf_clock_class_set_is_absolute(clock, 1);
+               if (ret) {
+                       _PERROR("%s", "cannot set clock class's absolute option");
+                       goto error;
+               }
        }
 
        ret = apply_clock_class_offset(ctx, clock);
@@ -4597,7 +4622,7 @@ end:
 static
 int move_ctx_stream_classes_to_trace(struct ctx *ctx)
 {
-       int ret;
+       int ret = 0;
        GHashTableIter iter;
        gpointer key, stream_class;
 
@@ -4622,7 +4647,7 @@ end:
 
 BT_HIDDEN
 struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(FILE *efd,
-               uint64_t clock_class_offset_ns)
+               uint64_t clock_class_offset_ns, const char *name)
 {
        int ret;
        struct ctx *ctx = NULL;
@@ -4634,6 +4659,12 @@ struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(FILE *efd,
                goto error;
        }
 
+       ret = bt_ctf_trace_set_name(trace, name);
+       if (ret) {
+               _FPERROR(efd, "cannot set trace's name to `%s`", name);
+               goto error;
+       }
+
        /* Set packet header to NULL to override the default one */
        ret = bt_ctf_trace_set_packet_header_type(trace, NULL);
        if (ret) {
@@ -4730,9 +4761,21 @@ int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
                assert(ctx->current_scope &&
                        ctx->current_scope->parent_scope == NULL);
 
+               /* Environment */
+               bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
+                       ret = visit_env(ctx, iter);
+                       if (ret) {
+                               _PERROR("error while visiting environment block (%d)",
+                                       ret);
+                               goto end;
+                       }
+               }
+
+               assert(ctx->current_scope &&
+                       ctx->current_scope->parent_scope == NULL);
+
                /*
-                * Visit clocks first since any early integer can be mapped
-                * to one.
+                * Visit clock blocks.
                 */
                bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
                        ret = visit_clock_decl(ctx, iter);
@@ -4776,19 +4819,6 @@ int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
                        _PWARNING("%s", "\"callsite\" blocks are not supported as of this version");
                }
 
-               /* Environment */
-               bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
-                       ret = visit_env(ctx, iter);
-                       if (ret) {
-                               _PERROR("error while visiting environment block (%d)",
-                                       ret);
-                               goto end;
-                       }
-               }
-
-               assert(ctx->current_scope &&
-                       ctx->current_scope->parent_scope == NULL);
-
                /* Trace */
                bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
                        ret = visit_trace_decl(ctx, iter);
This page took 0.031971 seconds and 4 git commands to generate.