X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Fctf%2Fcommon%2Fmetadata%2Fvisitor-generate-ir.c;h=f8f9538bf89d45ca34f7e535e138b6384d35a3c1;hb=f828aeda606803f3ab8abe50c6077efe78fdb527;hp=56069e5cd6d6d26c9a236ec1325598c21c0d9598;hpb=cf76ce92f8f8ae74ec9e1305e8ef83ac1bc4fb26;p=babeltrace.git diff --git a/plugins/ctf/common/metadata/visitor-generate-ir.c b/plugins/ctf/common/metadata/visitor-generate-ir.c index 56069e5c..f8f9538b 100644 --- a/plugins/ctf/common/metadata/visitor-generate-ir.c +++ b/plugins/ctf/common/metadata/visitor-generate-ir.c @@ -592,8 +592,8 @@ struct ctx *ctx_create(struct bt_ctf_trace *trace, goto error; } - ctx->stream_classes = g_hash_table_new_full(g_direct_hash, - g_direct_equal, NULL, (GDestroyNotify) bt_put); + ctx->stream_classes = g_hash_table_new_full(g_int64_hash, + g_int64_equal, g_free, (GDestroyNotify) bt_put); if (!ctx->stream_classes) { BT_LOGE_STR("Failed to allocate a GHashTable."); goto error; @@ -882,7 +882,6 @@ int get_unary_signed(struct bt_list_head *head, int64_t *value) int uexpr_type = node->u.unary_expression.type; int uexpr_link = node->u.unary_expression.link; int cond = node->type != NODE_UNARY_EXPRESSION || - (uexpr_type != UNARY_UNSIGNED_CONSTANT) || (uexpr_type != UNARY_UNSIGNED_CONSTANT && uexpr_type != UNARY_SIGNED_CONSTANT) || uexpr_link != UNARY_LINK_UNKNOWN || i != 0; @@ -891,7 +890,7 @@ int get_unary_signed(struct bt_list_head *head, int64_t *value) goto end; } - switch (node->u.unary_expression.type) { + switch (uexpr_type) { case UNARY_UNSIGNED_CONSTANT: *value = (int64_t) node->u.unary_expression.u.unsigned_constant; @@ -1651,7 +1650,7 @@ int visit_typealias(struct ctx *ctx, struct ctf_node *target, /* Do not allow typedef and typealias of untagged variants */ if (bt_ctf_field_type_is_variant(type_decl)) { if (bt_ctf_field_type_variant_get_tag_name(type_decl)) { - _BT_LOGE_NODE(node, + _BT_LOGE_NODE(target, "Type definition of untagged variant field type is not allowed."); ret = -EPERM; goto end; @@ -1663,7 +1662,7 @@ int visit_typealias(struct ctx *ctx, struct ctf_node *target, * abstract or not (if it has an identifier). Check it here. */ if (qdummy_field_name != 0) { - _BT_LOGE_NODE(node, + _BT_LOGE_NODE(target, "Expecting empty identifier: id=\"%s\"", g_quark_to_string(qdummy_field_name)); ret = -EINVAL; @@ -3622,6 +3621,7 @@ int visit_event_decl(struct ctx *ctx, struct ctf_node *node) if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) { GList *keys = NULL; + int64_t *new_stream_id; struct bt_ctf_stream_class *new_stream_class; size_t stream_class_count = g_hash_table_size(ctx->stream_classes) + @@ -3634,6 +3634,7 @@ int visit_event_decl(struct ctx *ctx, struct ctf_node *node) switch (stream_class_count) { case 0: /* Create implicit stream class if there's none */ + stream_id = 0; new_stream_class = create_reset_stream_class(ctx); if (!new_stream_class) { _BT_LOGE_NODE(node, @@ -3642,7 +3643,8 @@ int visit_event_decl(struct ctx *ctx, struct ctf_node *node) goto error; } - ret = bt_ctf_stream_class_set_id(new_stream_class, 0); + ret = bt_ctf_stream_class_set_id(new_stream_class, + stream_id); if (ret) { _BT_LOGE_NODE(node, "Cannot set stream class's ID: " @@ -3651,18 +3653,26 @@ int visit_event_decl(struct ctx *ctx, struct ctf_node *node) goto error; } - stream_id = 0; + new_stream_id = g_new0(int64_t, 1); + if (!new_stream_id) { + BT_LOGE_STR("Failed to allocate a int64_t."); + ret = -ENOMEM; + goto error; + } + + *new_stream_id = stream_id; /* Move reference to visitor's context */ g_hash_table_insert(ctx->stream_classes, - (gpointer) stream_id, new_stream_class); + new_stream_id, new_stream_class); + new_stream_id = NULL; new_stream_class = NULL; break; case 1: /* Single stream class: get its ID */ if (g_hash_table_size(ctx->stream_classes) == 1) { keys = g_hash_table_get_keys(ctx->stream_classes); - stream_id = (int64_t) keys->data; + stream_id = *((int64_t *) keys->data); g_list_free(keys); } else { assert(bt_ctf_trace_get_stream_class_count( @@ -3687,8 +3697,7 @@ int visit_event_decl(struct ctx *ctx, struct ctf_node *node) assert(stream_id >= 0); /* We have the stream ID now; get the stream class if found */ - stream_class = g_hash_table_lookup(ctx->stream_classes, - (gpointer) stream_id); + stream_class = g_hash_table_lookup(ctx->stream_classes, &stream_id); bt_get(stream_class); if (!stream_class) { stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace, @@ -3766,63 +3775,146 @@ end: } static -int auto_map_fields_to_trace_clock_class(struct ctx *ctx, - struct bt_ctf_field_type *packet_context_field_type, - const char **field_names) +int auto_map_field_to_trace_clock_class(struct ctx *ctx, + struct bt_ctf_field_type *ft) { - _BT_CTF_FIELD_TYPE_INIT(ft); - struct bt_ctf_clock_class *clock_class = NULL; + struct bt_ctf_clock_class *clock_class_to_map_to = NULL; struct bt_ctf_clock_class *mapped_clock_class = NULL; int ret = 0; - const char **field_name; + int64_t clock_class_count; - if (ctx->decoder_config.strict) { + if (!ft || !bt_ctf_field_type_is_integer(ft)) { goto end; } - if (!packet_context_field_type) { + mapped_clock_class = + bt_ctf_field_type_integer_get_mapped_clock_class(ft); + if (mapped_clock_class) { goto end; } - if (!bt_ctf_field_type_is_structure(packet_context_field_type)) { + clock_class_count = bt_ctf_trace_get_clock_class_count(ctx->trace); + assert(clock_class_count >= 0); + + switch (clock_class_count) { + case 0: + /* + * No clock class exists in the trace at this + * point. Create an implicit one at 1 GHz, + * named `default`, and use this clock class. + */ + clock_class_to_map_to = bt_ctf_clock_class_create("default", + 1000000000); + if (!clock_class_to_map_to) { + BT_LOGE_STR("Cannot create a clock class."); + ret = -1; + goto end; + } + + ret = bt_ctf_trace_add_clock_class(ctx->trace, + clock_class_to_map_to); + if (ret) { + BT_LOGE_STR("Cannot add clock class to trace."); + goto end; + } + break; + case 1: + /* + * Only one clock class exists in the trace at + * this point: use this one. + */ + clock_class_to_map_to = + bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0); + assert(clock_class_to_map_to); + break; + default: + /* + * Timestamp field not mapped to a clock class + * and there's more than one clock class in the + * trace: this is an error. + */ + BT_LOGE_STR("Timestamp field found with no mapped clock class, " + "but there's more than one clock class in the trace at this point."); + ret = -1; goto end; } - if (bt_ctf_trace_get_clock_class_count(ctx->trace) != 1) { + assert(clock_class_to_map_to); + ret = bt_ctf_field_type_integer_set_mapped_clock_class(ft, + clock_class_to_map_to); + if (ret) { + BT_LOGE("Cannot map field type's field to trace's clock class: " + "clock-class-name=\"%s\", ret=%d", + bt_ctf_clock_class_get_name(clock_class_to_map_to), + ret); goto end; } - clock_class = bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0); - assert(clock_class); +end: + bt_put(clock_class_to_map_to); + bt_put(mapped_clock_class); + return ret; +} - for (field_name = field_names; *field_name; field_name++) { - ft = bt_ctf_field_type_structure_get_field_type_by_name( - packet_context_field_type, *field_name); +static +int auto_map_fields_to_trace_clock_class(struct ctx *ctx, + struct bt_ctf_field_type *root_ft, const char *field_name) +{ + int ret = 0; + int64_t i, count; - if (ft && bt_ctf_field_type_is_integer(ft)) { - mapped_clock_class = - bt_ctf_field_type_integer_get_mapped_clock_class(ft); + if (!root_ft) { + goto end; + } - if (!mapped_clock_class) { - ret = bt_ctf_field_type_integer_set_mapped_clock_class( - ft, clock_class); - if (ret) { - BT_LOGE("Cannot map field type's field to trace's clock class: " - "field-name=\"%s\", ret=%d", - *field_name, ret); - goto end; - } + if (!bt_ctf_field_type_is_structure(root_ft) && + !bt_ctf_field_type_is_variant(root_ft)) { + goto end; + } + + if (bt_ctf_field_type_is_structure(root_ft)) { + count = bt_ctf_field_type_structure_get_field_count(root_ft); + } else { + count = bt_ctf_field_type_variant_get_field_count(root_ft); + } + + assert(count >= 0); + + for (i = 0; i < count; i++) { + _BT_CTF_FIELD_TYPE_INIT(ft); + const char *name; + + if (bt_ctf_field_type_is_structure(root_ft)) { + ret = bt_ctf_field_type_structure_get_field_by_index( + root_ft, &name, &ft, i); + } else if (bt_ctf_field_type_is_variant(root_ft)) { + ret = bt_ctf_field_type_variant_get_field_by_index( + root_ft, &name, &ft, i); + } + + assert(ret == 0); + + if (strcmp(name, field_name) == 0) { + ret = auto_map_field_to_trace_clock_class(ctx, ft); + if (ret) { + BT_LOGE("Cannot automatically map field to trace's clock class: " + "field-name=\"%s\"", field_name); + bt_put(ft); + goto end; } } - BT_PUT(mapped_clock_class); - BT_PUT(ft); + ret = auto_map_fields_to_trace_clock_class(ctx, ft, field_name); + bt_put(ft); + if (ret) { + BT_LOGE("Cannot automatically map structure or variant field type's fields to trace's clock class: " + "field-name=\"%s\", root-field-name=\"%s\"", + field_name, name); + goto end; + } } end: - bt_put(mapped_clock_class); - bt_put(clock_class); - bt_put(ft); return ret; } @@ -3883,8 +3975,7 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, goto error; } - ptr = g_hash_table_lookup(ctx->stream_classes, - (gpointer) id); + ptr = g_hash_table_lookup(ctx->stream_classes, &id); if (ptr) { _BT_LOGE_NODE(node, "Duplicate stream class (same ID): id=%" PRId64, @@ -3903,12 +3994,6 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, _SET(set, _STREAM_ID_SET); } else if (!strcmp(left, "event.header")) { - const char *field_names[] = { - "timestamp", - "ts", - NULL, - }; - if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) { _BT_LOGE_NODE(node, "Duplicate `event.header` entry in stream class."); @@ -3929,10 +4014,10 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, assert(decl); ret = auto_map_fields_to_trace_clock_class(ctx, - decl, field_names); + decl, "timestamp"); if (ret) { _BT_LOGE_NODE(node, - "Cannot automatically map specific event header field type fields to trace's clock class."); + "Cannot automatically map specific event header field type fields named `timestamp` to trace's clock class."); goto error; } @@ -3978,12 +4063,6 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, _SET(set, _STREAM_EVENT_CONTEXT_SET); } else if (!strcmp(left, "packet.context")) { - const char *field_names[] = { - "timestamp_begin", - "timestamp_end", - NULL, - }; - if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) { _BT_LOGE_NODE(node, "Duplicate `packet.context` entry in stream class."); @@ -4004,10 +4083,18 @@ int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node, assert(decl); ret = auto_map_fields_to_trace_clock_class(ctx, - decl, field_names); + decl, "timestamp_begin"); + if (ret) { + _BT_LOGE_NODE(node, + "Cannot automatically map specific packet context field type fields named `timestamp_begin` to trace's clock class."); + goto error; + } + + ret = auto_map_fields_to_trace_clock_class(ctx, + decl, "timestamp_end"); if (ret) { _BT_LOGE_NODE(node, - "Cannot automatically map specific packet context field type fields to trace's clock class."); + "Cannot automatically map specific packet context field type fields named `timestamp_end` to trace's clock class."); goto error; } @@ -4050,6 +4137,7 @@ static int visit_stream_decl(struct ctx *ctx, struct ctf_node *node) { int64_t id; + int64_t *new_id; int set = 0; int ret = 0; struct ctf_node *iter; @@ -4150,7 +4238,7 @@ int visit_stream_decl(struct ctx *ctx, struct ctf_node *node) */ existing_stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace, id); - if (g_hash_table_lookup(ctx->stream_classes, (gpointer) id) || + if (g_hash_table_lookup(ctx->stream_classes, &id) || existing_stream_class) { _BT_LOGE_NODE(node, "Duplicate stream class (same ID): id=%" PRId64, @@ -4159,8 +4247,16 @@ int visit_stream_decl(struct ctx *ctx, struct ctf_node *node) goto error; } + new_id = g_new0(int64_t, 1); + if (!new_id) { + BT_LOGE_STR("Failed to allocate a int64_t."); + ret = -ENOMEM; + goto error; + } + *new_id = id; + /* Move reference to visitor's context */ - g_hash_table_insert(ctx->stream_classes, (gpointer) (int64_t) id, + g_hash_table_insert(ctx->stream_classes, new_id, stream_class); stream_class = NULL; goto end; @@ -4443,14 +4539,12 @@ int visit_env(struct ctx *ctx, struct ctf_node *node) goto error; } - if (!ctx->decoder_config.strict) { - if (strcmp(left, "tracer_name") == 0) { - if (strncmp(right, "lttng", 5) == 0) { - BT_LOGI("Non-strict mode: detected LTTng trace from `%s` environment value: " - "tracer-name=\"%s\"", - left, right); - ctx->is_lttng = 1; - } + if (strcmp(left, "tracer_name") == 0) { + if (strncmp(right, "lttng", 5) == 0) { + BT_LOGI("Detected LTTng trace from `%s` environment value: " + "tracer-name=\"%s\"", + left, right); + ctx->is_lttng = 1; } } @@ -4712,6 +4806,14 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } + if (freq == -1ULL || freq == 0) { + _BT_LOGE_NODE(entry_node, + "Invalid clock class frequency: freq=%" PRIu64, + freq); + ret = -EINVAL; + goto error; + } + ret = bt_ctf_clock_class_set_frequency(clock, freq); if (ret) { _BT_LOGE_NODE(entry_node, @@ -4748,7 +4850,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, _SET(set, _CLOCK_PRECISION_SET); } else if (!strcmp(left, "offset_s")) { - uint64_t offset_s; + int64_t offset_s; if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) { _BT_LOGE_DUP_ATTR(entry_node, "offset_s", @@ -4757,7 +4859,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = get_unary_unsigned( + ret = get_unary_signed( &entry_node->u.ctf_expression.right, &offset_s); if (ret) { _BT_LOGE_NODE(entry_node, @@ -4775,7 +4877,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, _SET(set, _CLOCK_OFFSET_S_SET); } else if (!strcmp(left, "offset")) { - uint64_t offset; + int64_t offset; if (_IS_SET(set, _CLOCK_OFFSET_SET)) { _BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class"); @@ -4783,7 +4885,7 @@ int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node, goto error; } - ret = get_unary_unsigned( + ret = get_unary_signed( &entry_node->u.ctf_expression.right, &offset); if (ret) { _BT_LOGE_NODE(entry_node, @@ -4908,7 +5010,9 @@ int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node) } clock_node->visited = TRUE; - clock = bt_ctf_clock_class_create(NULL); + + /* CTF 1.8's default frequency for a clock class is 1 GHz */ + clock = bt_ctf_clock_class_create(NULL, 1000000000); if (!clock) { _BT_LOGE_NODE(clock_node, "Cannot create default clock class.");