X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=lttng-events.c;h=5307b722b237991935d75a93f61d04caac36e06b;hb=6a2ecd2e89615a83b8559a7e959277a66f8bff17;hp=b748cce62c8f464f8743f5794d50ee927fa0c57e;hpb=f513b2bf88afa9a36a725fbf8e91e3a3f3efebc9;p=lttng-modules.git diff --git a/lttng-events.c b/lttng-events.c index b748cce6..5307b722 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -1736,6 +1736,62 @@ int _lttng_struct_statedump(struct lttng_session *session, return ret; } +/* + * Must be called with sessions_mutex held. + */ +static +int _lttng_variant_type_statedump(struct lttng_session *session, + const struct lttng_type *type, + size_t nesting) +{ + int ret; + uint32_t i, nr_choices; + + ret = print_tabs(session, nesting); + if (ret) + return ret; + ret = lttng_metadata_printf(session, + "variant <_%s> {\n", + type->u.variant.tag_name); + if (ret) + return ret; + nr_choices = type->u.variant.nr_choices; + for (i = 0; i < nr_choices; i++) { + const struct lttng_event_field *iter_field; + + iter_field = &type->u.variant.choices[i]; + ret = _lttng_field_statedump(session, iter_field, nesting + 1); + if (ret) + return ret; + } + ret = print_tabs(session, nesting); + if (ret) + return ret; + ret = lttng_metadata_printf(session, + "}"); + return ret; +} + +/* + * Must be called with sessions_mutex held. + */ +static +int _lttng_variant_statedump(struct lttng_session *session, + const struct lttng_event_field *field, + size_t nesting) +{ + int ret; + + ret = _lttng_variant_type_statedump(session, + &field->type, nesting); + if (ret) + return ret; + ret = lttng_metadata_printf(session, + "_%s;\n", + field->name); + return ret; +} + /* * Must be called with sessions_mutex held. */ @@ -1747,7 +1803,7 @@ int _lttng_array_compound_statedump(struct lttng_session *session, int ret; const struct lttng_type *elem_type; - /* Only array of structures are currently supported. */ + /* Only array of structures and variants are currently supported. */ elem_type = field->type.u.array_compound.elem_type; switch (elem_type->atype) { case atype_struct: @@ -1755,6 +1811,11 @@ int _lttng_array_compound_statedump(struct lttng_session *session, if (ret) return ret; break; + case atype_variant: + ret = _lttng_variant_type_statedump(session, elem_type, nesting); + if (ret) + return ret; + break; default: return -EINVAL; } @@ -1779,7 +1840,7 @@ int _lttng_sequence_compound_statedump(struct lttng_session *session, length_name = field->type.u.sequence_compound.length_name; - /* Only array of structures are currently supported. */ + /* Only array of structures and variants are currently supported. */ elem_type = field->type.u.sequence_compound.elem_type; switch (elem_type->atype) { case atype_struct: @@ -1787,6 +1848,11 @@ int _lttng_sequence_compound_statedump(struct lttng_session *session, if (ret) return ret; break; + case atype_variant: + ret = _lttng_variant_type_statedump(session, elem_type, nesting); + if (ret) + return ret; + break; default: return -EINVAL; } @@ -1797,6 +1863,110 @@ int _lttng_sequence_compound_statedump(struct lttng_session *session, return ret; } +/* + * Must be called with sessions_mutex held. + */ +static +int _lttng_enum_statedump(struct lttng_session *session, + const struct lttng_event_field *field, + size_t nesting) +{ + const struct lttng_enum_desc *enum_desc; + const struct lttng_integer_type *container_type; + int ret; + unsigned int i, nr_entries; + + enum_desc = field->type.u.basic.enumeration.desc; + container_type = &field->type.u.basic.enumeration.container_type; + nr_entries = enum_desc->nr_entries; + + ret = print_tabs(session, nesting); + if (ret) + goto end; + ret = lttng_metadata_printf(session, + "enum : integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u; } {\n", + container_type->size, + container_type->alignment, + container_type->signedness, + (container_type->encoding == lttng_encode_none) + ? "none" + : (container_type->encoding == lttng_encode_UTF8) + ? "UTF8" + : "ASCII", + container_type->base); + if (ret) + goto end; + /* Dump all entries */ + for (i = 0; i < nr_entries; i++) { + const struct lttng_enum_entry *entry = &enum_desc->entries[i]; + int j, len; + + ret = print_tabs(session, nesting + 1); + if (ret) + goto end; + ret = lttng_metadata_printf(session, + "\""); + if (ret) + goto end; + len = strlen(entry->string); + /* Escape the character '"' */ + for (j = 0; j < len; j++) { + char c = entry->string[j]; + + switch (c) { + case '"': + ret = lttng_metadata_printf(session, + "\\\""); + break; + case '\\': + ret = lttng_metadata_printf(session, + "\\\\"); + break; + default: + ret = lttng_metadata_printf(session, + "%c", c); + break; + } + if (ret) + goto end; + } + ret = lttng_metadata_printf(session, + "\" = "); + if (ret) + goto end; + if (entry->start.signedness) + ret = lttng_metadata_printf(session, + "%lld", (long long) entry->start.value); + else + ret = lttng_metadata_printf(session, + "%llu", entry->start.value); + if (ret) + goto end; + if (entry->start.signedness == entry->end.signedness && + entry->start.value == entry->end.value) { + ret = lttng_metadata_printf(session, + ",\n"); + } else { + if (entry->end.signedness) { + ret = lttng_metadata_printf(session, + " ... %lld,\n", (long long) entry->end.value); + } else { + ret = lttng_metadata_printf(session, + " ... %llu,\n", entry->end.value); + } + } + if (ret) + goto end; + } + ret = print_tabs(session, nesting); + if (ret) + goto end; + ret = lttng_metadata_printf(session, "} _%s;\n", + field->name); +end: + return ret; +} + /* * Must be called with sessions_mutex held. */ @@ -1831,13 +2001,7 @@ int _lttng_field_statedump(struct lttng_session *session, field->name); break; case atype_enum: - ret = print_tabs(session, nesting); - if (ret) - return ret; - ret = lttng_metadata_printf(session, - "%s _%s;\n", - field->type.u.basic.enumeration.name, - field->name); + ret = _lttng_enum_statedump(session, field, nesting); break; case atype_array: { @@ -1962,6 +2126,9 @@ int _lttng_field_statedump(struct lttng_session *session, case atype_sequence_compound: ret = _lttng_sequence_compound_statedump(session, field, nesting); break; + case atype_variant: + ret = _lttng_variant_statedump(session, field, nesting); + break; default: WARN_ON_ONCE(1); @@ -2444,6 +2611,9 @@ static int __init lttng_events_init(void) if (ret) return ret; ret = wrapper_get_pageblock_flags_mask_init(); + if (ret) + return ret; + ret = lttng_probes_init(); if (ret) return ret; ret = lttng_context_init();