X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fctf-ir%2Ftrace.c;h=1b1e5f82a3bfc0207d9deb89b526a8ca8a138dc7;hb=f6ccaed94e575af57fe6bf38154771bee4871a2a;hp=4a3027b48ec76517c055b5312e59f91c185a2bfa;hpb=50842bdc4c21f3de2b63e29cdac730af8b6dcca6;p=deliverable%2Fbabeltrace.git diff --git a/lib/ctf-ir/trace.c b/lib/ctf-ir/trace.c index 4a3027b48..1b1e5f82a 100644 --- a/lib/ctf-ir/trace.c +++ b/lib/ctf-ir/trace.c @@ -43,12 +43,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -350,7 +352,7 @@ int bt_trace_set_environment_field(struct bt_trace *trace, goto end; } - if (bt_identifier_is_valid(name)) { + if (!bt_identifier_is_valid(name)) { BT_LOGW("Invalid parameter: environment field's name is not a valid CTF identifier: " "trace-addr=%p, trace-name=\"%s\", " "env-name=\"%s\"", @@ -480,7 +482,7 @@ int64_t bt_trace_get_environment_field_count(struct bt_trace *trace) } ret = bt_attributes_get_count(trace->environment); - assert(ret >= 0); + BT_ASSERT(ret >= 0); end: return ret; @@ -706,7 +708,7 @@ bool packet_header_field_type_is_valid(struct bt_trace *trace, ret = bt_field_type_structure_get_field_by_index( packet_header_type, &field_name, NULL, 0); - assert(ret == 0); + BT_ASSERT(ret == 0); if (strcmp(field_name, "magic") != 0) { BT_LOGW("Invalid packet header field type: `magic` field must be the first field: " @@ -744,7 +746,7 @@ bool packet_header_field_type_is_valid(struct bt_trace *trace, } elem_ft = bt_field_type_array_get_element_type(field_type); - assert(elem_ft); + BT_ASSERT(elem_ft); if (!bt_field_type_is_integer(elem_ft)) { BT_LOGW("Invalid packet header field type: `uuid` field's element field type must be an integer field type: " @@ -1087,7 +1089,7 @@ bool event_header_field_type_is_valid(struct bt_trace *trace, goto invalid; } - assert(int_ft); + BT_ASSERT(int_ft); if (bt_field_type_integer_is_signed(int_ft)) { BT_LOGW("Invalid event header field type: `id` field must be an unsigned integer or enumeration field type: " "id-ft-addr=%p", int_ft); @@ -1108,6 +1110,34 @@ end: return is_valid; } +static +int check_packet_header_type_has_no_clock_class(struct bt_trace *trace) +{ + int ret = 0; + + if (trace->packet_header_type) { + struct bt_clock_class *clock_class = NULL; + + ret = bt_validate_single_clock_class(trace->packet_header_type, + &clock_class); + bt_put(clock_class); + if (ret || clock_class) { + BT_LOGW("Trace's packet header field type cannot " + "contain a field type which is mapped to " + "a clock class: " + "trace-addr=%p, trace-name=\"%s\", " + "clock-class-name=\"%s\"", + trace, bt_trace_get_name(trace), + clock_class ? + bt_clock_class_get_name(clock_class) : + NULL); + ret = -1; + } + } + + return ret; +} + int bt_trace_add_stream_class(struct bt_trace *trace, struct bt_stream_class *stream_class) { @@ -1127,6 +1157,7 @@ int bt_trace_add_stream_class(struct bt_trace *trace, struct bt_field_type *stream_event_ctx_type = NULL; int64_t event_class_count; struct bt_trace *current_parent_trace = NULL; + struct bt_clock_class *expected_clock_class = NULL; if (!trace) { BT_LOGW_STR("Invalid parameter: trace is NULL."); @@ -1168,7 +1199,7 @@ int bt_trace_add_stream_class(struct bt_trace *trace, event_class_count = bt_stream_class_get_event_class_count(stream_class); - assert(event_class_count >= 0); + BT_ASSERT(event_class_count >= 0); if (stream_class->clock) { struct bt_clock_class *stream_clock_class = @@ -1214,6 +1245,85 @@ int bt_trace_add_stream_class(struct bt_trace *trace, ret = -1; goto end; } + + if (stream_class->clock_class && + stream_class->clock_class != + stream_class->clock->clock_class) { + /* + * Stream class already has an expected clock + * class, but it does not match its clock's + * class. + */ + BT_LOGW("Invalid parameter: stream class's clock's " + "class does not match stream class's " + "expected clock class: " + "stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", " + "stream-class-name=\"%s\", " + "expected-clock-class-addr=%p, " + "expected-clock-class-name=\"%s\"", + stream_class, + bt_stream_class_get_id(stream_class), + bt_stream_class_get_name(stream_class), + expected_clock_class, + bt_clock_class_get_name(expected_clock_class)); + } else if (!stream_class->clock_class) { + /* + * Set expected clock class to stream class's + * clock's class. + */ + expected_clock_class = + bt_get(stream_class->clock->clock_class); + } + } + + if (!stream_class->frozen) { + /* + * Stream class is not frozen yet. Validate that the + * stream class contains at most a single clock class + * because the previous + * bt_stream_class_add_event_class() calls did not make + * this validation since the stream class's direct field + * types (packet context, event header, event context) + * could change afterwards. This stream class is about + * to be frozen and those field types won't be changed + * if this function succeeds. + * + * At this point we're also sure that the stream class's + * clock, if any, has the same class as the stream + * class's expected clock class, if any. This is why, if + * bt_stream_class_validate_single_clock_class() + * succeeds below, the call to + * bt_stream_class_map_clock_class() at the end of this + * function is safe because it maps to the same, single + * clock class. + */ + ret = bt_stream_class_validate_single_clock_class(stream_class, + &expected_clock_class); + if (ret) { + BT_LOGW("Invalid parameter: stream class or one of its " + "event classes contains a field type which is " + "not recursively mapped to the expected " + "clock class: " + "stream-class-addr=%p, " + "stream-class-id=%" PRId64 ", " + "stream-class-name=\"%s\", " + "expected-clock-class-addr=%p, " + "expected-clock-class-name=\"%s\"", + stream_class, bt_stream_class_get_id(stream_class), + bt_stream_class_get_name(stream_class), + expected_clock_class, + expected_clock_class ? + bt_clock_class_get_name(expected_clock_class) : + NULL); + goto end; + } + } + + ret = check_packet_header_type_has_no_clock_class(trace); + if (ret) { + /* check_packet_header_type_has_no_clock_class() logs errors */ + goto end; } /* @@ -1451,6 +1561,14 @@ int bt_trace_add_stream_class(struct bt_trace *trace, bt_stream_class_freeze(stream_class); bt_trace_freeze(trace); + /* + * It is safe to set the stream class's unique clock class + * now because the stream class is frozen. + */ + if (expected_clock_class) { + BT_MOVE(stream_class->clock_class, expected_clock_class); + } + /* Notifiy listeners of the trace's schema modification. */ bt_stream_class_visit(stream_class, bt_trace_object_modification, trace); @@ -1477,10 +1595,11 @@ end: g_free(ec_validation_outputs); bt_validation_output_put_types(&trace_sc_validation_output); bt_put(current_parent_trace); - assert(!packet_header_type); - assert(!packet_context_type); - assert(!event_header_type); - assert(!stream_event_ctx_type); + bt_put(expected_clock_class); + BT_ASSERT(!packet_header_type); + BT_ASSERT(!packet_context_type); + BT_ASSERT(!event_header_type); + BT_ASSERT(!stream_event_ctx_type); return ret; } @@ -1645,8 +1764,8 @@ bt_bool bt_trace_has_clock_class(struct bt_trace *trace, { struct search_query query = { .value = clock_class, .found = 0 }; - assert(trace); - assert(clock_class); + BT_ASSERT(trace); + BT_ASSERT(clock_class); g_ptr_array_foreach(trace->clocks, value_exists, &query); return query.found; @@ -1694,7 +1813,7 @@ int append_trace_metadata(struct bt_trace *trace, g_string_append(context->string, "trace {\n"); g_string_append(context->string, "\tmajor = 1;\n"); g_string_append(context->string, "\tminor = 8;\n"); - assert(trace->native_byte_order == BT_BYTE_ORDER_LITTLE_ENDIAN || + BT_ASSERT(trace->native_byte_order == BT_BYTE_ORDER_LITTLE_ENDIAN || trace->native_byte_order == BT_BYTE_ORDER_BIG_ENDIAN || trace->native_byte_order == BT_BYTE_ORDER_NETWORK); @@ -1751,8 +1870,8 @@ void append_env_metadata(struct bt_trace *trace, env_field_value_obj = bt_attributes_get_field_value( trace->environment, i); - assert(entry_name); - assert(env_field_value_obj); + BT_ASSERT(entry_name); + BT_ASSERT(env_field_value_obj); switch (bt_value_get_type(env_field_value_obj)) { case BT_VALUE_TYPE_INTEGER: @@ -1762,7 +1881,7 @@ void append_env_metadata(struct bt_trace *trace, ret = bt_value_integer_get(env_field_value_obj, &int_value); - assert(ret == 0); + BT_ASSERT(ret == 0); g_string_append_printf(context->string, "\t%s = %" PRId64 ";\n", entry_name, int_value); @@ -1776,7 +1895,7 @@ void append_env_metadata(struct bt_trace *trace, ret = bt_value_string_get(env_field_value_obj, &str_value); - assert(ret == 0); + BT_ASSERT(ret == 0); escaped_str = g_strescape(str_value, NULL); if (!escaped_str) { BT_LOGE("Cannot escape string: string=\"%s\"", @@ -2069,8 +2188,8 @@ int bt_trace_object_modification(struct bt_visitor_object *object, size_t i; struct bt_trace *trace = trace_ptr; - assert(trace); - assert(object); + BT_ASSERT(trace); + BT_ASSERT(object); if (trace->listeners->len == 0) { goto end; @@ -2164,6 +2283,12 @@ int bt_trace_set_is_static(struct bt_trace *trace) goto end; } + ret = check_packet_header_type_has_no_clock_class(trace); + if (ret) { + /* check_packet_header_type_has_no_clock_class() logs errors */ + goto end; + } + trace->is_static = BT_TRUE; bt_trace_freeze(trace); BT_LOGV("Set trace static: addr=%p, name=\"%s\"",