From 8cac01060ddc9ceeabc7efd3043bda1138bbf248 Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Wed, 29 Jul 2026 16:41:22 +0000 Subject: [PATCH 01/10] Use native lttng-ust 2.16 BLOB fields instead of the uint8_t text work-around Raw bytes -- structs, unions, opaque buffers -- were recorded as ctf_sequence_text / ctf_array_text of uint8_t and read back with a patched lttng-ust that emitted the full length instead of stopping at the first NUL. lttng-ust 2.16 has first-class BLOB fields, so record them as real blobs: ctf_array_text(uint8_t, ...) -> lttng_ust_field_fixed_length_blob ctf_sequence_text(uint8_t, ...) -> lttng_ust_field_variable_length_blob and map those to babeltrace blob_static / blob_dynamic. Genuine char text (ctf_string and char sequences/arrays) is untouched: 82 fixed and 767 variable blobs are generated, and the 10 char text fields stay as they were. - yaml_ast_lttng.rb: the aggregate arms emit blob macros, variable when a length_type is present and fixed otherwise. - LTTng.rb: TracepointField learns the two blob macros, a media_type, and blobify() for the positional dialect; print_tracepoint renders through call_string, since a blob's arguments are not the ctf_* ones. - gen_probe_base.rb: payload_length_field_location() names the MIP-1 field location next to length_field_name(), which it is built from. - gen_babeltrace_model_helper.rb: implicit_length_field? extends the companion-length rule to variable-length blobs; blobs become blob_static/blob_dynamic; name_packed_struct() is the one owner of "these raw bytes are really a struct", shared by the text and blob arms. - gen_babeltrace_lib_helper.rb: blob_static/blob_dynamic reuse the string readback path -- a blob carries the same bytes a text sequence did. - meta_parameters.rb: a nullable pointer-to-struct downgrades fixed to variable so its length collapses to 0 when the pointer is null. - babeltrace_thapi.in: request CTF 2 and MIP 1, both required to write and read BLOB fields, when babeltrace >= 2.1. - configure.ac: metababel >= 2.0.0, the first release that generates blob field classes and MIP-1 field locations. Co-Authored-By: Claude Opus 5 (1M context) --- backends/opencl/gen_babeltrace_cl_model.rb | 14 ++++-- configure.ac | 2 +- utils/LTTng.rb | 42 +++++++++++++--- utils/babeltrace_thapi.in | 8 +++- utils/gen_babeltrace_lib_helper.rb | 2 +- utils/gen_babeltrace_model_helper.rb | 56 ++++++++++++++++------ utils/gen_probe_base.rb | 9 +++- utils/meta_parameters.rb | 6 ++- utils/yaml_ast_lttng.rb | 8 ++-- 9 files changed, 113 insertions(+), 34 deletions(-) diff --git a/backends/opencl/gen_babeltrace_cl_model.rb b/backends/opencl/gen_babeltrace_cl_model.rb index 994f67aaf..7e1fac5ce 100644 --- a/backends/opencl/gen_babeltrace_cl_model.rb +++ b/backends/opencl/gen_babeltrace_cl_model.rb @@ -53,9 +53,17 @@ def parse_field(field) d[:field_class][:type] = unsigned?(field['type']) ? 'integer_unsigned' : 'integer_signed' d[:field_class][:field_value_range] = integer_size(field['type'], field['pointer']) d[:field_class][:preferred_display_base] = 16 if field['lttng'] == 'ctf_integer_hex' - when 'ctf_string', 'ctf_sequence_text' + when 'ctf_string' d[:field_class][:type] = 'string' d[:metadata] = { be_class: cl_to_class(field['type']) } if field['structure'] + when 'ctf_sequence_text' + # Raw bytes (structs/buffers) are now recorded as a variable-length BLOB. + d[:field_class][:type] = 'blob_dynamic' + d[:field_class][:length_field_location] = payload_length_field_location(field['name']) + if field['structure'] + d[:field_class][:cast_type_is_struct] = true + d[:metadata] = { be_class: cl_to_class(field['type']) } + end when 'ctf_array' d[:field_class][:type] = 'array_static' d_field = parse_field({ 'lttng' => 'ctf_integer', 'type' => field['type'], 'pointer' => field['pointer'] }) @@ -65,13 +73,13 @@ def parse_field(field) d[:field_class][:type] = 'array_dynamic' d_field = parse_field({ 'lttng' => 'ctf_integer', 'type' => field['type'], 'pointer' => field['pointer'] }) d[:field_class][:element_field_class] = d_field[:field_class] - d[:field_class][:length_field_path] = "EVENT_PAYLOAD[\"_#{field['name']}_length\"]" + d[:field_class][:length_field_location] = payload_length_field_location(field['name']) when 'ctf_sequence_hex' d[:field_class][:type] = 'array_dynamic' d_field = parse_field({ 'lttng' => 'ctf_integer_hex', 'type' => field['type'], 'pointer' => field['pointer'] }) d[:field_class][:element_field_class] = d_field[:field_class] - d[:field_class][:length_field_path] = "EVENT_PAYLOAD[\"_#{field['name']}_length\"]" + d[:field_class][:length_field_location] = payload_length_field_location(field['name']) when 'ctf_enum' d[:field_class][:type] = unsigned?(field['type']) ? 'enumeration_unsigned' : 'enumeration_signed' enum_type = field['enum_type'] diff --git a/configure.ac b/configure.ac index 661244ebd..79b06d7ae 100644 --- a/configure.ac +++ b/configure.ac @@ -131,7 +131,7 @@ PKG_CHECK_MODULES([PROTOBUF], [protobuf >= 3.0]) AX_RUBY_EXTENSION([nokogiri], [yes]) AX_RUBY_EXTENSION([babeltrace2], [yes]) -AX_RUBY_EXTENSION([metababel >= 1.1.3], [yes]) +AX_RUBY_EXTENSION([metababel >= 2.0.0], [yes]) AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) diff --git a/utils/LTTng.rb b/utils/LTTng.rb index 96f1d836a..8bcce8385 100644 --- a/utils/LTTng.rb +++ b/utils/LTTng.rb @@ -76,13 +76,35 @@ class TracepointField ctf_sequence_network_hex: %i[type name expression length_type length], ctf_sequence_text: %i[type name expression length_type length], ctf_string: %i[name expression], + lttng_ust_field_fixed_length_blob: %i[name expression length media_type], + lttng_ust_field_variable_length_blob: %i[name expression length_type length media_type], } - attr_accessor :macro, :expression, :type, :provider_name, :enum_name, :length, :length_type, :cast + # IANA media type for arbitrary binary struct/buffer data recorded as a blob. + DEFAULT_MEDIA_TYPE = 'application/octet-stream'.freeze + attr_accessor :macro, :expression, :type, :provider_name, :enum_name, :length, :length_type, :cast, :media_type attr_reader :name + # Rewrite a positional uint8_t text sequence/array (raw bytes recorded as + # "text") into the equivalent 2.16 blob macro. Genuine char text is left + # alone. Shape in: [ctf_sequence_text, uint8_t, name, expr, len_type, len] + # or: [ctf_array_text, uint8_t, name, expr, len] + def self.blobify(args) + return args unless args.length > 1 && %i[ctf_sequence_text ctf_array_text].include?(args[0].to_sym) + return args unless args[1].to_sym == :uint8_t + + rest = args[2..-1] + case args[0].to_sym + when :ctf_sequence_text + [:lttng_ust_field_variable_length_blob, *rest, DEFAULT_MEDIA_TYPE] + when :ctf_array_text + [:lttng_ust_field_fixed_length_blob, *rest, DEFAULT_MEDIA_TYPE] + end + end + def initialize(*args) return unless args.length > 0 + args = self.class.blobify(args) desc = FIELDS[args[0].to_sym] raise "Invalid field #{args[0]}!" unless desc @@ -100,10 +122,18 @@ def initialize(*args) end def call_string - str = "#{@macro}(" - str << [@provider_name, @enum_name, @type, @name, @cast ? "(#{@cast})(#{@expression})" : @expression, - @length_type, @length].compact.join(', ') - str << ')' + expr = @cast ? "(#{@cast})(#{@expression})" : @expression + media_type = "\"#{@media_type || DEFAULT_MEDIA_TYPE}\"" + args = + case @macro + when :lttng_ust_field_fixed_length_blob + [@name, expr, @length, media_type] + when :lttng_ust_field_variable_length_blob + [@name, expr, @length_type, @length, media_type] + else + [@provider_name, @enum_name, @type, @name, expr, @length_type, @length] + end + "#{@macro}(#{args.compact.join(', ')})" end def name=(n) @@ -141,7 +171,7 @@ def self.print_tracepoint(namespace, tp, phase = nil, suffix: nil) ), TP_FIELDS( EOF - fields = tp[phase || 'fields'].to_a.collect { |(f, *args)| "#{f}(#{args.join(', ')})" } + fields = tp[phase || 'fields'].to_a.collect { |field| TracepointField.new(*field).call_string } puts indented(fields) unless fields.empty? puts <<~EOF ) diff --git a/utils/babeltrace_thapi.in b/utils/babeltrace_thapi.in index 3e3b187fb..c86760df6 100755 --- a/utils/babeltrace_thapi.in +++ b/utils/babeltrace_thapi.in @@ -64,8 +64,10 @@ module BTComponentClassRefinement end end refine(BT2::BTGraph.singleton_class) do + # MIP 1 is required to read CTF2 traces that use BLOB fields (lttng-ust >= + # 2.16). All THAPI metababel components advertise MIP 1 support. def new(handle = nil, retain: true, auto_release: true, - mip_version: 0) + mip_version: 1) obj = super obj.plugins_path = [] obj.cli_v = [] @@ -234,7 +236,9 @@ def get_and_add_components(graph, names, l_inputs) BT2.bt_version_get_patch].join('.') semantic_version_str += BT2.bt_version_get_development_stage if BT2.bt_version_get_development_stage - params['ctf-version'] = '1.8' if Gem::Version.new(semantic_version_str) >= Gem::Version.new('2.1.0') + # BLOB fields (lttng-ust >= 2.16) are only expressible in CTF 2, so the + # intermediate sink must write CTF 2 (requires babeltrace >= 2.1). + params['ctf-version'] = '2' if Gem::Version.new(semantic_version_str) >= Gem::Version.new('2.1.0') graph.add(comp, 'ctf_sink', params: params) # We cast integers, because babeltrace2 infers the type from the value # passed rather than from the one the *_params.yaml declares. diff --git a/utils/gen_babeltrace_lib_helper.rb b/utils/gen_babeltrace_lib_helper.rb index 42e6d9726..50fc3139f 100644 --- a/utils/gen_babeltrace_lib_helper.rb +++ b/utils/gen_babeltrace_lib_helper.rb @@ -50,7 +50,7 @@ def render_field(naming, field) end when 'double', 'single' plain - when 'string' + when 'string', 'blob_static', 'blob_dynamic' be_class ? render_packed_struct(name, be_class) : %(s << "#{name}: \#{defi["#{name}"].inspect}") when 'array_dynamic', 'array_static' element = fc[:element_field_class] diff --git a/utils/gen_babeltrace_model_helper.rb b/utils/gen_babeltrace_model_helper.rb index 50620d31b..7bc15549f 100644 --- a/utils/gen_babeltrace_model_helper.rb +++ b/utils/gen_babeltrace_model_helper.rb @@ -24,11 +24,16 @@ def build_ast_registry(naming, expect_bitfields:) registry end -# The rows describing one field: the sequence's companion length field, when it -# has one, then the field itself. +# The rows describing one field: the companion length field, when the field has +# one, then the field itself. Variable-length sequences and blobs are the two +# shapes lttng gives an implicit `__length`. +def implicit_length_field?(macro) + macro.match?(/ctf_sequence/) || macro == 'lttng_ust_field_variable_length_blob' +end + def field_types_name(macro, type, name, lttng) rows = [] - rows << ['ctf_integer', 'size_t', length_field_name(name), nil] if macro.match?(/ctf_sequence/) + rows << ['ctf_integer', 'size_t', length_field_name(name), nil] if implicit_length_field?(macro) rows << [macro, type, name, lttng] rows end @@ -63,6 +68,24 @@ def element_field_class(registry, lttng, lttng_name) fc end +# Raw bytes -- whether recorded as text or as a blob -- may really be a struct. +# Resolve the typedef chain to its underlying name, and when that names a struct +# say which FFI class reads it back. +def name_packed_struct(registry, field, member, type) + types_by_name = registry.types_by_name + t = type.sub(' *', '') + t = types_by_name[t].type.name while types_by_name.include?(t) && types_by_name[t].type.is_a?(YAMLCAst::CustomType) + member[:metadata] = { be_class: registry.class_namer.call(t) } if registry.struct_names.include?(t) + + # Too complicated, not sure why `struct_names` is not enough + return if field[:cast_type].end_with?('*') + + packed = registry.struct_names.include?(t) || + types_by_name[t]&.type.is_a?(YAMLCAst::Union) || + type.start_with?('struct') + field[:cast_type_is_struct] = true if packed +end + def gen_bt_field_model(registry, lttng_name, type, name, lttng) types_by_name = registry.types_by_name member = { name: name } @@ -89,23 +112,28 @@ def gen_bt_field_model(registry, lttng_name, type, name, lttng) field[:type] = 'array_dynamic' field[:element_field_class] = element_field_class(registry, lttng, lttng_name) field[:element_field_class][:cast_type] = type.match(/(.*) \*/)[1] - field[:length_field_path] = "EVENT_PAYLOAD[\"#{length_field_name(name)}\"]" + field[:length_field_location] = payload_length_field_location(name) when 'ctf_array', 'ctf_array_hex' field[:type] = 'array_static' field[:element_field_class] = element_field_class(registry, lttng, lttng_name) field[:length] = lttng.length - when 'ctf_string' + when 'ctf_string', 'ctf_sequence_text', 'ctf_array_text' + # Genuine text: char strings and char sequences/arrays. field[:type] = 'string' - when 'ctf_sequence_text', 'ctf_array_text' - field[:type] = 'string' - t = type.sub(' *', '') - t = types_by_name[t].type.name while types_by_name.include?(t) && types_by_name[t].type.is_a?(YAMLCAst::CustomType) - member[:metadata] = { be_class: registry.class_namer.call(t) } if registry.struct_names.include?(t) - - # Too complicated, not sure why `all_struct_names` is not enough - if !field[:cast_type].end_with?('*') && (registry.struct_names.include?(t) || types_by_name[t]&.type.is_a?(YAMLCAst::Union) || type.start_with?('struct')) - field[:cast_type_is_struct] = true + name_packed_struct(registry, field, member, type) + when 'lttng_ust_field_fixed_length_blob', 'lttng_ust_field_variable_length_blob' + # Raw bytes -- a struct, a union, or an opaque buffer. A fixed-length blob + # knows its size; a variable-length one reads it from the companion length + # field lttng emits alongside it. + if lttng_name == 'lttng_ust_field_fixed_length_blob' + field[:type] = 'blob_static' + field[:length] = lttng.length + else + field[:type] = 'blob_dynamic' + field[:length_field_location] = payload_length_field_location(name) end + field[:media_type] = lttng.media_type if lttng.media_type + name_packed_struct(registry, field, member, type) else raise "unsupported lttng type: #{lttng.inspect}" end diff --git a/utils/gen_probe_base.rb b/utils/gen_probe_base.rb index 95a72bdf4..121785772 100644 --- a/utils/gen_probe_base.rb +++ b/utils/gen_probe_base.rb @@ -63,6 +63,13 @@ def length_field_name?(name) LENGTH_FIELD_PATTERN.match?(name.to_s) end +# Where the model points a variable-length field at its companion length field. +# MIP 1 addresses it as a scope plus a path, replacing the MIP 0 +# `EVENT_PAYLOAD["..."]` string. +def payload_length_field_location(name) + { root_scope: 'BT_FIELD_LOCATION_SCOPE_EVENT_PAYLOAD', items: [length_field_name(name)] } +end + def print_tracepoint(provider, c, dir = nil) name = tracepoint_event_name(c, dir) @@ -132,7 +139,7 @@ def print_struct_tracepoint(provider, t) ), TP_FIELDS( ctf_integer_hex(uintptr_t, p, (uintptr_t)(p)) - ctf_sequence_text(uint8_t, p_val, p, size_t, (p ? sizeof(#{t}) : 0)) + lttng_ust_field_variable_length_blob(p_val, p, size_t, (p ? sizeof(#{t}) : 0), "application/octet-stream") ) ) diff --git a/utils/meta_parameters.rb b/utils/meta_parameters.rb index ba802dae9..eb088bb05 100644 --- a/utils/meta_parameters.rb +++ b/utils/meta_parameters.rb @@ -156,8 +156,10 @@ def initialize(command, name) lttngt = t.type.lttng_type(command.type_classes) lttngt.name = name + '_val' - if lttngt.macro == :ctf_array_text - lttngt.macro = :ctf_sequence_text + if lttngt.macro == :lttng_ust_field_fixed_length_blob + # A pointer-to-struct scalar may be null, so record it as a variable-length + # blob whose length collapses to 0 when the pointer is null. + lttngt.macro = :lttng_ust_field_variable_length_blob lttngt.expression = sanitize_expression("#{name}") checks = check_for_null("#{name}") lttngt.length = sanitize_expression("#{lttngt.length}", checks) diff --git a/utils/yaml_ast_lttng.rb b/utils/yaml_ast_lttng.rb index 461632864..486a22765 100644 --- a/utils/yaml_ast_lttng.rb +++ b/utils/yaml_ast_lttng.rb @@ -55,7 +55,7 @@ def lttng_type(_type_classes) class Struct def lttng_type(_type_classes) ev = LTTng::TracepointField.new - ev.macro = :ctf_array_text + ev.macro = :lttng_ust_field_fixed_length_blob ev.type = :uint8_t ev.length = "sizeof(struct #{name})" ev @@ -69,7 +69,7 @@ def [](name) class Union def lttng_type(_type_classes) ev = LTTng::TracepointField.new - ev.macro = :ctf_array_text + ev.macro = :lttng_ust_field_fixed_length_blob ev.type = :uint8_t ev.length = "sizeof(union #{name})" ev @@ -129,7 +129,7 @@ def lttng_type(type_classes) ev.macro = :ctf_integer ev.type = :int32_t when :aggregate - ev.macro = :ctf_array_text + ev.macro = :lttng_ust_field_fixed_length_blob ev.type = :uint8_t ev.length = "sizeof(#{name})" else @@ -189,12 +189,12 @@ def lttng_type(type_classes, length: nil, length_type: nil) ev.macro = :"ctf_#{lttng_arr_type}" ev.type = :int32_t when :aggregate - ev.macro = :"ctf_#{lttng_arr_type}_text" ev.type = :uint8_t if ev.length ev.length = "(#{ev.length}) * sizeof(#{type.name})" ev.length_type = 'size_t' end + ev.macro = ev.length_type ? :lttng_ust_field_variable_length_blob : :lttng_ust_field_fixed_length_blob else super(type_classes) end From b2ddac26fd9c17a5b2a13b811309577f1050cfb7 Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Mon, 21 Sep 2026 14:44:23 +0000 Subject: [PATCH 02/10] gen: let the classifier say which types are raw bytes Two facts about a byte buffer were spread over four places. A `void *` became a `uint8_t` array in three copies of the same `if pointee is Void` in meta_parameters.rb, and `yaml_ast_lttng.rb` then had to override the classifier -- `type.name == 'uint8_t' ? :aggregate : category_of(...)` -- because uint8_t is in INT_TYPES and so classifies as an integer. The override carried a comment apologising for itself, and it fired 158 times: 78 arrays the generator had synthesized and 80 the headers genuinely declare as `uint8_t *` (ze pRawData, pKernelBinary). Say it once on each side instead: - TypeClasses#array_category_of(name) answers what an ARRAY of a type is. A run of bytes is binary data -- an opaque buffer, or a struct in packed form -- so it reports :aggregate and records as raw bytes; everything else delegates to category_of. BYTE_TYPES names uint8_t and int8_t next to the other fixed C type lists, and an API's own typedefs of them are found transitively. - MetaParameter#element_type(pointee) is the one place that says a pointer to void points at bytes. category_of keeps its five arms: it answers what a VALUE of a type is, and one byte is just a number. Putting bytes there instead broke `typedef uint8_t ze_bool_t`, which is a boolean, not a buffer -- the distinction the two questions now draw. int8_t is included so a signed byte buffer works if an API declares one; none does today, and no typedef of either is used as an array element, so all 49 generated files are byte-identical. Co-Authored-By: Claude Opus 5 (1M context) --- utils/meta_parameters.rb | 27 +++++++++------------------ utils/yaml_ast.rb | 19 ++++++++++++++++++- utils/yaml_ast_lttng.rb | 5 +---- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/utils/meta_parameters.rb b/utils/meta_parameters.rb index eb088bb05..4e7f597d6 100644 --- a/utils/meta_parameters.rb +++ b/utils/meta_parameters.rb @@ -32,6 +32,12 @@ def lttng_out_type class MetaParameter attr_reader :name, :command, :lttng_type + # What a pointer points at, for a meta-parameter that traces the pointee. + # `void *` names no type, so say what the trace records: a run of bytes. + def element_type(pointee) + pointee.is_a?(YAMLCAst::Void) ? YAMLCAst::CustomType.new(name: 'uint8_t') : pointee + end + # Here rather than in each generator that walks these, so every caller asks # the direction question the same way. LTTNG_TYPE_BY_DIRECTION = { start: :lttng_in_type, stop: :lttng_out_type, nil => :lttng_type }.freeze @@ -212,12 +218,7 @@ def initialize(command, name, size) sz = sanitize_expression("#{size}", checks) st = INT_SIGN_MAP["#{s.type}"] ? 'size_t' : "#{s.type}" end - tt = if t.type.is_a?(YAMLCAst::Void) - YAMLCAst::CustomType.new(name: 'uint8_t') - else - t.type - end - y = YAMLCAst::Array.new(type: tt) + y = YAMLCAst::Array.new(type: element_type(t.type)) lttngt = y.lttng_type(command.type_classes, length: sz, length_type: st) lttngt.name = name + '_vals' lttngt.expression = sanitize_expression("#{name}") @@ -293,12 +294,7 @@ def initialize(command, name, size) raise "Type is not a pointer: #{t}!" unless t.is_a?(YAMLCAst::Pointer) check_for_null("#{name}") - tt = if t.type.is_a?(YAMLCAst::Void) - YAMLCAst::CustomType.new(name: 'uint8_t') - else - t.type - end - y = YAMLCAst::Array.new(type: tt) + y = YAMLCAst::Array.new(type: element_type(t.type)) lttngt = y.lttng_type(command.type_classes, length: size, length_type: nil) lttngt.name = name + '_vals' lttngt.expression = sanitize_expression("#{name}") @@ -339,12 +335,7 @@ def initialize(command, name, size) sz = sanitize_expression("#{size}", checks) st = "#{s.type}" end - tt = if t.type.type.is_a?(YAMLCAst::Void) - YAMLCAst::CustomType.new(name: 'uint8_t') - else - t.type.type - end - y = YAMLCAst::Array.new(type: tt) + y = YAMLCAst::Array.new(type: element_type(t.type.type)) lttngt = y.lttng_type(command.type_classes, length: sz, length_type: st) lttngt.name = name + '_val_vals' lttngt.expression = sanitize_expression("*#{name}") diff --git a/utils/yaml_ast.rb b/utils/yaml_ast.rb index f17bc6997..6a4aafa1f 100644 --- a/utils/yaml_ast.rb +++ b/utils/yaml_ast.rb @@ -428,6 +428,14 @@ def find_types_map(types, cast_type, map) FFI_INT_TYPE_MAP = INT_TYPE_MAP.map { |k, v| [k, v[2]] }.to_h INT_TYPES = INT_TYPE_MAP.keys +# The C names for a byte. A buffer of these is binary data -- an opaque payload +# or a packed struct -- rather than a run of numbers worth printing, so it is +# recorded as raw bytes. An API's own typedefs of them are found transitively. +BYTE_TYPES = %w[ + uint8_t + int8_t +].freeze + # Integer types the tracer logs in hex rather than decimal. An API can name # more of its own -- see ApiModel's hex_ints. HEX_INT_TYPES = %w[ @@ -471,7 +479,7 @@ def object_typedef?(t, types) # API's own: a typedef chain bottoms out in `int` or `uint32_t`, so the # category has to contain both to answer "is this an integer?" in one lookup. TypeClasses = Struct.new(:objects, :integers, :hex_ints, :enums, :structs, :unions, :pointers, - keyword_init: true) do + :bytes, keyword_init: true) do # The one category a typedef name falls into, or nil when this API never # names it. The order is the answer: an object typedef is a pointer under the # hood and a hex int is an integer, so the more specific category has to win. @@ -487,6 +495,14 @@ def category_of(name) end end + # The category an ARRAY of `name` falls into. A run of bytes is binary data -- + # an opaque buffer, or a struct in its packed form -- so it records as raw + # bytes exactly as an aggregate does. One byte on its own is just a number, + # which is why this answer differs from category_of's. + def array_category_of(name) + bytes.include?(name) ? :aggregate : category_of(name) + end + def aggregate?(name) category_of(name) == :aggregate end @@ -507,6 +523,7 @@ def find_all_types(types, hex_ints: []) TypeClasses.new( objects: objects, integers: integers, pointers: pointers, hex_ints: HEX_INT_TYPES + hex_ints, + bytes: transitive_closure(types, BYTE_TYPES.dup), enums: find_types(types, YAMLCAst::Enum), structs: find_types(types, YAMLCAst::Struct), unions: find_types(types, YAMLCAst::Union) diff --git a/utils/yaml_ast_lttng.rb b/utils/yaml_ast_lttng.rb index 486a22765..de4ffec80 100644 --- a/utils/yaml_ast_lttng.rb +++ b/utils/yaml_ast_lttng.rb @@ -172,10 +172,7 @@ def lttng_type(type_classes, length: nil, length_type: nil) ev.macro = :"ctf_#{lttng_arr_type}_text" ev.type = type.name when YAMLCAst::CustomType - # A uint8_t array is binary data or text rather than a run of numbers, - # so it gets an aggregate's treatment -- bytes, sized in bytes -- even - # though the name classifies as an integer. - case type.name == 'uint8_t' ? :aggregate : type_classes.category_of(type.name) + case type_classes.array_category_of(type.name) when :address ev.macro = :"ctf_#{lttng_arr_type}_hex" ev.type = :uintptr_t From c7140b1cd3b7b9e34b35b44fcade5637819853cf Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Mon, 21 Sep 2026 15:09:06 +0000 Subject: [PATCH 03/10] gen: say blob where we mean blob, and delete the rewrite that hid it Fifty-odd declarations wrote `ctf_sequence_text, uint8_t` -- "text" for bytes that are not text -- and LTTng.blobify rewrote each one into a blob macro on its way past. Nothing that read those declarations could take them at face value, and two readers did not: - backends/ze/gen_babeltrace_ze_model.rb asked for a ctf_sequence_text row, so gen_bt_field_model typed 175 struct-dump fields as `string` in btx_ze_model.yaml while the tracepoints wrote blobs. The reader and the writer disagreed about the wire. - opencl's LTTngFieldTuple read a field's name and expression from hardcoded tuple positions that assume a `type` slot. A blob has none, so every slot after it shifted. Say it once, at the source: - the 45 YAML rows across cuda/hip/opencl/ze name the blob macro and carry a media type; the one genuine `char` row in itt_events.yaml is untouched. - opencl_model.rb's array broker and the two hand-written tuple sites name it too, so blobify has no callers left and is deleted. - LTTngFieldTuple reads slot positions from TracepointField::FIELDS, which already declares them per macro, rather than re-encoding them. - gen_babeltrace_cl_model.rb dispatches on the blob macro, and asks implicit_length_field? which fields need a companion length, instead of matching /ctf_sequence/ by name. Also drop a dead branch: the array arm chose between a fixed and a variable blob, but it is only reached once a length is known -- a length-less array is logged as its address -- and the length is always a run-time size_t, so the fixed case could not occur. 47 of 49 generated files are byte-identical. The two that move are the fixes: btx_ze_model.yaml (175 fields string -> blob_dynamic) and opencl_model.yaml (the macro name it records). Verified on ze_peak and a program hitting both uint8_t shapes: structs, uuids and a 768-byte kernel binary all match the values the program itself saw. Co-Authored-By: Claude Opus 5 (1M context) --- backends/cuda/cuda_events.yaml | 6 ++-- backends/cuda/cuda_meta_parameters.yaml | 32 +++++++++--------- backends/hip/hip_meta_parameters.yaml | 36 ++++++++++---------- backends/opencl/gen_babeltrace_cl_model.rb | 5 ++- backends/opencl/opencl_events.yaml | 2 +- backends/opencl/opencl_model.rb | 23 ++++++++++--- backends/opencl/opencl_tracepoints.rb | 37 +++++++++------------ backends/opencl/opencl_wrapper_events.yaml | 4 +-- backends/ze/gen_babeltrace_ze_model.rb | 9 ++--- backends/ze/ze_events.yaml | 38 +++++++++++----------- utils/LTTng.rb | 18 ---------- utils/yaml_ast_lttng.rb | 12 ++++--- 12 files changed, 107 insertions(+), 115 deletions(-) diff --git a/backends/cuda/cuda_events.yaml b/backends/cuda/cuda_events.yaml index 6d0867a8e..160170b13 100644 --- a/backends/cuda/cuda_events.yaml +++ b/backends/cuda/cuda_events.yaml @@ -18,7 +18,7 @@ lttng_ust_cuda_args: - [ ctf_integer_hex, uintptr_t, f, "(uintptr_t)f" ] - [ ctf_integer, size_t, argIndex, argIndex ] - [ ctf_integer_hex, uintptr_t, kernelParam, "(uintptr_t)kernelParam" ] - - [ ctf_sequence_text, uint8_t, kernelParam_val, "(uint8_t *)kernelParam", size_t, "kernelParam ? argSize : 0" ] + - [ lttng_ust_field_variable_length_blob, kernelParam_val, "(uint8_t *)kernelParam", size_t, "kernelParam ? argSize : 0" , "application/octet-stream"] lttng_ust_cuda_profiling: events: - name: event_profiling @@ -52,7 +52,7 @@ lttng_ust_cuda_exports: fields: - [ ctf_integer_hex, uintptr_t, pExportTableId, "(uintptr_t)pExportTableId" ] - [ ctf_integer_hex, size_t, exportOffset, exportOffset ] - - [ ctf_sequence_text, uint8_t, pExportTableId_val, pExportTableId, size_t, "sizeof(CUuuid)" ] + - [ lttng_ust_field_variable_length_blob, pExportTableId_val, pExportTableId, size_t, "sizeof(CUuuid)" , "application/octet-stream"] lttng_ust_cuda_properties: events: - name: device @@ -65,4 +65,4 @@ lttng_ust_cuda_properties: - [ ctf_integer, int, ordinal, ordinal ] - [ ctf_integer_hex, int, device, device ] - [ ctf_string, name, name ] - - [ ctf_sequence_text, uint8_t, uuid, uuid, size_t, "sizeof(CUuuid)" ] + - [ lttng_ust_field_variable_length_blob, uuid, uuid, size_t, "sizeof(CUuuid)" , "application/octet-stream"] diff --git a/backends/cuda/cuda_meta_parameters.yaml b/backends/cuda/cuda_meta_parameters.yaml index d2f083804..de00b8ce3 100644 --- a/backends/cuda/cuda_meta_parameters.yaml +++ b/backends/cuda/cuda_meta_parameters.yaml @@ -295,7 +295,7 @@ meta_parameters: cuMipmappedArrayGetLevel: - [OutScalar, pLevelArray] cuMemGetHandleForAddressRange: - - [OutLTTng, handle, ctf_sequence_text, uint8_t, handle_val, handle, size_t, "handleType == CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD ? sizeof(int) : 0"] + - [OutLTTng, handle, lttng_ust_field_variable_length_blob, handle_val, handle, size_t, "handleType == CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD ? sizeof(int) : 0", "application/octet-stream"] cuMemAddressReserve: - [OutScalar, ptr] cuMemCreate: @@ -311,10 +311,10 @@ meta_parameters: - [InScalar, location] - [OutScalar, flags] cuMemExportToShareableHandle: - - [OutLTTng, shareableHandle, ctf_sequence_text, uint8_t, shareableHandle_val, shareableHandle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] + - [OutLTTng, shareableHandle, lttng_ust_field_variable_length_blob, shareableHandle_val, shareableHandle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] cuMemImportFromShareableHandle: - [OutScalar, handle] - - [InLTTng, osHandle, ctf_sequence_text, uint8_t, osHandle_val, osHandle, size_t, "shHandleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] + - [InLTTng, osHandle, lttng_ust_field_variable_length_blob, osHandle_val, osHandle, size_t, "shHandleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] cuMemGetAllocationGranularity: - [InScalar, prop] - [OutScalar, granularity] @@ -327,15 +327,15 @@ meta_parameters: cuMemAllocAsync_ptsz: - [OutScalar, dptr] cuMemPoolSetAttribute: - - [InLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == CU_MEMPOOL_ATTR_REUSE_FOLLOW_EVENT_DEPENDENCIES ? sizeof(int) : \ attr == CU_MEMPOOL_ATTR_REUSE_ALLOW_OPPORTUNISTIC ? sizeof(int) : \ attr == CU_MEMPOOL_ATTR_REUSE_ALLOW_INTERNAL_DEPENDENCIES ? sizeof(int) : \ attr == CU_MEMPOOL_ATTR_RELEASE_THRESHOLD ? sizeof(cuuint64_t) : \ attr == CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : \ - attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] + attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] cuMemPoolGetAttribute: - - [OutLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [OutLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == CU_MEMPOOL_ATTR_REUSE_FOLLOW_EVENT_DEPENDENCIES ? sizeof(int) : \ attr == CU_MEMPOOL_ATTR_REUSE_ALLOW_OPPORTUNISTIC ? sizeof(int) : \ attr == CU_MEMPOOL_ATTR_REUSE_ALLOW_INTERNAL_DEPENDENCIES ? sizeof(int) : \ @@ -343,7 +343,7 @@ meta_parameters: attr == CU_MEMPOOL_ATTR_RESERVED_MEM_CURRENT ? sizeof(cuuint64_t) : \ attr == CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : \ attr == CU_MEMPOOL_ATTR_USED_MEM_CURRENT ? sizeof(cuuint64_t) : \ - attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] + attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] cuMemPoolSetAccess: - [InArray, map, count] cuMemPoolGetAccess: @@ -357,9 +357,9 @@ meta_parameters: cuMemAllocFromPoolAsync_ptsz: - [OutScalar, dptr] cuMemPoolExportToShareableHandle: - - [OutLTTng, handle_out, ctf_sequence_text, uint8_t, handle_out_val, handle_out, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] + - [OutLTTng, handle_out, lttng_ust_field_variable_length_blob, handle_out_val, handle_out, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] cuMemPoolImportFromShareableHandle: - - [InLTTng, handle, ctf_sequence_text, uint8_t, handle_val, handle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] + - [InLTTng, handle, lttng_ust_field_variable_length_blob, handle_val, handle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] - [OutScalar, pool_out] cuMemPoolExportPointer: - [OutScalar, shareData_out] @@ -373,7 +373,7 @@ meta_parameters: - [InScalar, prop] - [OutScalar, granularity] cuPointerGetAttribute: - - [OutLTTng, data, ctf_sequence_text, uint8_t, data_val, data, size_t, "\ + - [OutLTTng, data, lttng_ust_field_variable_length_blob, data_val, data, size_t, "\ attribute == CU_POINTER_ATTRIBUTE_CONTEXT ? sizeof(CUcontext) : \ attribute == CU_POINTER_ATTRIBUTE_MEMORY_TYPE ? sizeof(unsigned int) : \ attribute == CU_POINTER_ATTRIBUTE_DEVICE_POINTER ? sizeof(CUdeviceptr) : \ @@ -393,14 +393,14 @@ meta_parameters: attribute == CU_POINTER_ATTRIBUTE_MEMPOOL_HANDLE ? sizeof(CUmemoryPool) : \ attribute == CU_POINTER_ATTRIBUTE_MAPPING_SIZE ? sizeof(size_t) : \ attribute == CU_POINTER_ATTRIBUTE_MAPPING_BASE_ADDR ? sizeof(void *) : \ - attribute == CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID ? sizeof(unsigned long long) : 0"] + attribute == CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID ? sizeof(unsigned long long) : 0", "application/octet-stream"] cuMemRangeGetAttribute: - [OutArray, data, dataSize] cuMemRangeGetAttributes: - [InArray, attributes, numAttributes] - [InArray, dataSizes, numAttributes] cuPointerSetAttribute: - - [InLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "attribute == CU_POINTER_ATTRIBUTE_SYNC_MEMOPS ? sizeof(uint8_t) : 0"] + - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "attribute == CU_POINTER_ATTRIBUTE_SYNC_MEMOPS ? sizeof(uint8_t) : 0", "application/octet-stream"] cuPointerGetAttributes: - [InArray, attributes, numAttributes] - [OutArray, data, numAttributes] @@ -626,15 +626,15 @@ meta_parameters: cuGraphMemFreeNodeGetParams: - [OutScalar, dptr_out] cuDeviceGetGraphMemAttribute: - - [OutLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [OutLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == CU_GRAPH_MEM_ATTR_USED_MEM_CURRENT ? sizeof(cuuint64_t) : \ attr == CU_GRAPH_MEM_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : \ attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_CURRENT ? sizeof(cuuint64_t) : \ - attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] + attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] cuDeviceSetGraphMemAttribute: - - [InLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == CU_GRAPH_MEM_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : \ - attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] + attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] cuGraphClone: - [OutScalar, phGraphClone] cuGraphNodeFindInClone: diff --git a/backends/hip/hip_meta_parameters.yaml b/backends/hip/hip_meta_parameters.yaml index 41aacc6bf..c2887b29e 100644 --- a/backends/hip/hip_meta_parameters.yaml +++ b/backends/hip/hip_meta_parameters.yaml @@ -93,7 +93,7 @@ meta_parameters: hipPointerGetAttributes: - [OutScalar, attributes] hipPointerGetAttribute: - - [OutLTTng, data, ctf_sequence_text, uint8_t, data_val, data, size_t, "\ + - [OutLTTng, data, lttng_ust_field_variable_length_blob, data_val, data, size_t, "\ attribute == HIP_POINTER_ATTRIBUTE_CONTEXT ? 0 : \ attribute == HIP_POINTER_ATTRIBUTE_MEMORY_TYPE ? sizeof(unsigned int) : \ attribute == HIP_POINTER_ATTRIBUTE_DEVICE_POINTER ? sizeof(hipDeviceptr_t) : \ @@ -110,7 +110,7 @@ meta_parameters: attribute == HIP_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES ? 0 : \ attribute == HIP_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE ? 0 : \ attribute == HIP_POINTER_ATTRIBUTE_ACCESS_FLAGS ? sizeof(hipMemAccessFlags) : \ - attribute == HIP_POINTER_ATTRIBUTE_MEMPOOL_HANDLE ? 0 : 0"] + attribute == HIP_POINTER_ATTRIBUTE_MEMPOOL_HANDLE ? 0 : 0", "application/octet-stream"] hipImportExternalSemaphore: - [InScalar, semHandleDesc] - [OutScalar, extSem_out] @@ -146,7 +146,7 @@ meta_parameters: hipMallocAsync: - [OutScalar, dev_ptr] hipMemPoolSetAttribute: - - [InLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == hipMemPoolReuseFollowEventDependencies ? sizeof(int) : \ attr == hipMemPoolReuseAllowOpportunistic ? sizeof(int) : \ attr == hipMemPoolReuseAllowInternalDependencies ? sizeof(int) : \ @@ -154,9 +154,9 @@ meta_parameters: attr == hipMemPoolAttrReservedMemCurrent ? 0 : \ attr == hipMemPoolAttrReservedMemHigh ? 0 : \ attr == hipMemPoolAttrUsedMemCurrent ? 0 : \ - attr == hipMemPoolAttrUsedMemHigh ? 0 : 0"] + attr == hipMemPoolAttrUsedMemHigh ? 0 : 0", "application/octet-stream"] hipMemPoolGetAttribute: - - [OutLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [OutLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == hipMemPoolReuseFollowEventDependencies ? sizeof(int) : \ attr == hipMemPoolReuseAllowOpportunistic ? sizeof(int) : \ attr == hipMemPoolReuseAllowInternalDependencies ? sizeof(int) : \ @@ -164,7 +164,7 @@ meta_parameters: attr == hipMemPoolAttrReservedMemCurrent ? 0 : \ attr == hipMemPoolAttrReservedMemHigh ? 0 : \ attr == hipMemPoolAttrUsedMemCurrent ? 0 : \ - attr == hipMemPoolAttrUsedMemHigh ? 0 : 0"] + attr == hipMemPoolAttrUsedMemHigh ? 0 : 0", "application/octet-stream"] hipMemPoolSetAccess: - [InArray, desc_list, count] hipMemPoolGetAccess: @@ -176,11 +176,11 @@ meta_parameters: hipMallocFromPoolAsync: - [OutScalar, dev_ptr] hipMemPoolExportToShareableHandle: - - [OutLTTng, shared_handle, ctf_sequence_text, uint8_t, shared_handle_val, shared_handle, size_t, "\ - handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] + - [OutLTTng, shared_handle, lttng_ust_field_variable_length_blob, shared_handle_val, shared_handle, size_t, "\ + handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] hipMemPoolImportFromShareableHandle: - - [InLTTng, shared_handle, ctf_sequence_text, uint8_t, shared_handle_val, shared_handle, size_t, "\ - handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] + - [InLTTng, shared_handle, lttng_ust_field_variable_length_blob, shared_handle_val, shared_handle, size_t, "\ + handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] - [OutScalar, mem_pool] hipMemPoolExportPointer: - [OutScalar, export_data] @@ -516,15 +516,15 @@ meta_parameters: hipGraphEventWaitNodeGetEvent: - [OutScalar, event_out] hipDeviceGetGraphMemAttribute: - - [OutLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [OutLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == hipGraphMemAttrUsedMemCurrent ? sizeof(uint64_t) : \ attr == hipGraphMemAttrUsedMemHigh ? sizeof(uint64_t) : \ attr == hipGraphMemAttrReservedMemCurrent ? sizeof(uint64_t) : \ - attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0"] + attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0", "application/octet-stream"] hipDeviceSetGraphMemAttribute: - - [InLTTng, value, ctf_sequence_text, uint8_t, value_val, value, size_t, "\ + - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == hipGraphMemAttrUsedMemHigh ? sizeof(uint64_t) : \ - attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0"] + attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0", "application/octet-stream"] hipUserObjectCreate: - [OutScalar, object_out] hipMemAddressReserve: @@ -533,8 +533,8 @@ meta_parameters: - [InScalar, prop] - [OutScalar, handle] hipMemExportToShareableHandle: - - [OutLTTng, shareableHandle, ctf_sequence_text, uint8_t, shareableHandle_val, shareableHandle, size_t, "\ - handleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] + - [OutLTTng, shareableHandle, lttng_ust_field_variable_length_blob, shareableHandle_val, shareableHandle, size_t, "\ + handleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] hipMemGetAccess: - [InScalar, location] - [OutScalar, flags] @@ -544,8 +544,8 @@ meta_parameters: hipMemGetAllocationPropertiesFromHandle: - [OutScalar, prop] hipMemImportFromShareableHandle: - - [InLTTng, osHandle, ctf_sequence_text, uint8_t, osHandle_val, osHandle, size_t, "\ - shHandleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] + - [InLTTng, osHandle, lttng_ust_field_variable_length_blob, osHandle_val, osHandle, size_t, "\ + shHandleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] - [OutScalar, handle] hipMemMapArrayAsync: - [InScalar, mapInfoList] diff --git a/backends/opencl/gen_babeltrace_cl_model.rb b/backends/opencl/gen_babeltrace_cl_model.rb index 7e1fac5ce..b98d3d229 100644 --- a/backends/opencl/gen_babeltrace_cl_model.rb +++ b/backends/opencl/gen_babeltrace_cl_model.rb @@ -56,8 +56,7 @@ def parse_field(field) when 'ctf_string' d[:field_class][:type] = 'string' d[:metadata] = { be_class: cl_to_class(field['type']) } if field['structure'] - when 'ctf_sequence_text' - # Raw bytes (structs/buffers) are now recorded as a variable-length BLOB. + when 'lttng_ust_field_variable_length_blob' d[:field_class][:type] = 'blob_dynamic' d[:field_class][:length_field_location] = payload_length_field_location(field['name']) if field['structure'] @@ -107,7 +106,7 @@ def parse_field(field) parsed_field[:field_class][:element_field_class][:cast_type] = match[1] end - if (field['array'] || field['structure']) && field['lttng'].match('ctf_sequence') + if (field['array'] || field['structure']) && implicit_length_field?(field['lttng']) additional_parsed_field = parse_field({ 'name' => length_field_name(sub_name), 'lttng' => 'ctf_integer', 'type' => 'size_t' }) diff --git a/backends/opencl/opencl_events.yaml b/backends/opencl/opencl_events.yaml index a53a3ce1b..32ebfd14c 100644 --- a/backends/opencl/opencl_events.yaml +++ b/backends/opencl/opencl_events.yaml @@ -110,7 +110,7 @@ lttng_ust_opencl_dump: - [ ctf_integer, uint64_t, enqueue_counter, enqueue_counter ] - [ ctf_integer, cl_uint, arg_index, arg_index ] - [ ctf_integer, size_t, arg_size, arg_size ] - - [ ctf_sequence_text, uint8_t, arg_value, arg_value, size_t, "arg_value == NULL ? 0 : arg_size" ] + - [ lttng_ust_field_variable_length_blob, arg_value, arg_value, size_t, "arg_value == NULL ? 0 : arg_size" , "application/octet-stream"] - name: svmptr_dump_event args: - [ uint64_t, enqueue_counter ] diff --git a/backends/opencl/opencl_model.rb b/backends/opencl/opencl_model.rb index 85f03059c..af35071d9 100644 --- a/backends/opencl/opencl_model.rb +++ b/backends/opencl/opencl_model.rb @@ -367,6 +367,14 @@ def initialize(command, name, nocheck: false) # rubocop:disable Lint/UnusedMetho @name = name end + # A variable-length blob always ships a run-time length. A fixed-size array + # has no length parameter of its own, so its size is the length. + def blob_length_args(stype, name, size) + return ['size_t', size] unless stype + + [CL_TYPE_MAP[stype] || stype, "#{name} == NULL ? 0 : #{size}"] + end + def lttng_array_type_broker(type, name, size, stype = nil) type = CL_TYPE_MAP[type] if CL_TYPE_MAP[type] if stype @@ -386,7 +394,11 @@ def lttng_array_type_broker(type, name, size, stype = nil) when *CL_FLOAT_SCALARS lttng_type = ["ctf_#{lttng_arr_type}_hex", CL_FLOAT_SCALARS_MAP[type]] when *CL_STRUCTS, 'void' - lttng_type = ["ctf_#{lttng_arr_type}_text", 'uint8_t'] + # Raw bytes rather than a run of numbers, so a blob. Its slots are not the + # ctf_* array ones: no element type, and a media type at the end. + return ['lttng_ust_field_variable_length_blob', name + '_vals', expr, + *blob_length_args(stype, name, size), + LTTng::TracepointField::DEFAULT_MEDIA_TYPE] else raise "Unknown Type: #{type.inspect} for #{name} in #{@command.prototype.name}!" end @@ -427,8 +439,8 @@ def initialize(command, name, nocheck: false) when *CL_FLOAT_SCALARS @lttng_in_type = ['ctf_float', type, name + '_val', nocheck ? "*#{name}" : "#{name} == NULL ? 0 : *#{name}"] when *CL_STRUCTS - @lttng_in_type = ['ctf_sequence_text', 'uint8_t', name + '_val', "(uint8_t *)#{name}", 'size_t', - "#{name} == NULL ? 0 : sizeof(#{type})"] + @lttng_in_type = ['lttng_ust_field_variable_length_blob', name + '_val', "(uint8_t *)#{name}", 'size_t', + "#{name} == NULL ? 0 : sizeof(#{type})", LTTng::TracepointField::DEFAULT_MEDIA_TYPE] else raise "Unknown Type: #{type.inspect}!" end @@ -721,8 +733,9 @@ def void_parameters? buffer_create_info = InMetaParameter.new(OPENCL_COMMANDS['clCreateSubBuffer'], 'buffer_create_info') buffer_create_info.instance_variable_set(:@lttng_in_type, - ['ctf_sequence_text', 'uint8_t', 'buffer_create_info_vals', 'buffer_create_info', 'size_t', - 'buffer_create_info == NULL ? 0 : (buffer_create_type == CL_BUFFER_CREATE_TYPE_REGION ? sizeof(cl_buffer_region) : 0)']) + ['lttng_ust_field_variable_length_blob', 'buffer_create_info_vals', 'buffer_create_info', 'size_t', + 'buffer_create_info == NULL ? 0 : (buffer_create_type == CL_BUFFER_CREATE_TYPE_REGION ? sizeof(cl_buffer_region) : 0)', + LTTng::TracepointField::DEFAULT_MEDIA_TYPE]) OPENCL_COMMANDS['clCreateSubBuffer'].meta_parameters.push buffer_create_info diff --git a/backends/opencl/opencl_tracepoints.rb b/backends/opencl/opencl_tracepoints.rb index 1c5d30e45..3ecb6b829 100644 --- a/backends/opencl/opencl_tracepoints.rb +++ b/backends/opencl/opencl_tracepoints.rb @@ -4,19 +4,25 @@ # tracepoint fields travel as raw [macro, *args] tuples rather than as # utils/LTTng.rb's TracepointField objects. module LTTngFieldTuple + # Which slot holds what is already declared once, per macro, by + # LTTng::TracepointField::FIELDS. Read the position from there rather than + # re-encoding it here: a macro with no `type` slot, such as a blob, would + # otherwise shift every field after it. + def self.slot(args, key) + i = LTTng::TracepointField::FIELDS.fetch(args[0].to_sym).index(key) + i && args[i + 1] + end + def self.name(*args) - case args[0] - when 'ctf_string' - args[1] - when 'ctf_enum' - args[4] - else - args[2] - end + slot(args, :name) + end + + def self.expression(*args) + slot(args, :expression) end def self.array?(*args) - args[0].match('array') || args[0].match('sequence') + args[0].match('array') || args[0].match('sequence') || args[0].match('blob') end def self.string?(*args) @@ -26,17 +32,6 @@ def self.string?(*args) def self.enum?(*args) args[0].match('enum') end - - def self.expression(*args) - case args[0] - when 'ctf_string' - args[2] - when 'ctf_enum' - args[5] - else - args[3] - end - end end def get_field(args, field) @@ -67,7 +62,7 @@ def get_field(args, field) res['string'] = true res.delete('pointer') end - res['enum_type'] = field[2] if LTTngFieldTuple.enum?(*field) + res['enum_type'] = LTTngFieldTuple.slot(field, :enum_name) if LTTngFieldTuple.enum?(*field) res['lttng'] = field[0] [name, res] end diff --git a/backends/opencl/opencl_wrapper_events.yaml b/backends/opencl/opencl_wrapper_events.yaml index af1eeee00..fc4c1ddb1 100644 --- a/backends/opencl/opencl_wrapper_events.yaml +++ b/backends/opencl/opencl_wrapper_events.yaml @@ -34,7 +34,7 @@ lttng_ust_opencl: - [ ctf_integer, size_t, cb, cb ] - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] - [ ctf_string, errinfo_val, errinfo ] - - [ ctf_sequence_text, uint8_t, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" ] + - [ lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" , "application/octet-stream"] - name: clCreateContextFromType_callback args: - [ "const char *", errinfo ] @@ -47,7 +47,7 @@ lttng_ust_opencl: - [ ctf_integer, size_t, cb, cb ] - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] - [ ctf_string, errinfo_val, errinfo ] - - [ ctf_sequence_text, uint8_t, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" ] + - [ lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" , "application/octet-stream"] - name: clSetMemObjectDestructorCallback_callback args: - [ cl_mem, memobj ] diff --git a/backends/ze/gen_babeltrace_ze_model.rb b/backends/ze/gen_babeltrace_ze_model.rb index 61eaf0a7e..acf978411 100644 --- a/backends/ze/gen_babeltrace_ze_model.rb +++ b/backends/ze/gen_babeltrace_ze_model.rb @@ -1,19 +1,20 @@ require_relative 'gen_ze_library_base' require_relative '../../utils/gen_babeltrace_model_helper' -# A length this side never reads: gen_bt_field_model's ctf_sequence_text branch -# takes the count from the companion length field instead. +# A length this side never reads: a variable-length blob takes its count from +# the companion length field instead. UNREAD_LENGTH = '0' # These are the rows print_struct_tracepoint emits into the provider, so both # sides of the wire describe the same fields. def gen_struct_event_bt_model(registry, provider, struct) address = LTTng::TracepointField.new('ctf_integer_hex', 'uintptr_t', 'p', 'p') - bytes = LTTng::TracepointField.new('ctf_sequence_text', 'uint8_t', 'p_val', 'p', 'size_t', UNREAD_LENGTH) + bytes = LTTng::TracepointField.new('lttng_ust_field_variable_length_blob', 'p_val', 'p', 'size_t', + UNREAD_LENGTH, LTTng::TracepointField::DEFAULT_MEDIA_TYPE) gen_bt_event(registry, provider, struct, [['ctf_integer_hex', "#{struct} *", 'p', address], - *field_types_name('ctf_sequence_text', "#{struct} *", 'p_val', bytes)]) + *field_types_name('lttng_ust_field_variable_length_blob', "#{struct} *", 'p_val', bytes)]) end # Each self-describing struct is traced as an event of its own, carrying the diff --git a/backends/ze/ze_events.yaml b/backends/ze/ze_events.yaml index 45b51a46a..58f25240b 100644 --- a/backends/ze/ze_events.yaml +++ b/backends/ze/ze_events.yaml @@ -8,7 +8,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer, uint32_t, deviceIdx, "deviceIdx"] - - [ctf_sequence_text, uint8_t, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(zes_device_properties_t)"] + - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(zes_device_properties_t)", "application/octet-stream"] - name: engineProperties args: - [zes_device_handle_t, hDevice] @@ -17,7 +17,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hEngines, "(uintptr_t)hEngines"] - - [ctf_sequence_text, uint8_t, pEngineProperties_val, pEngineProperties, size_t, "sizeof(zes_engine_properties_t)"] + - [lttng_ust_field_variable_length_blob, pEngineProperties_val, pEngineProperties, size_t, "sizeof(zes_engine_properties_t)", "application/octet-stream"] - name: engineStats args: - [zes_device_handle_t, hDevice] @@ -26,7 +26,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hEngines, "(uintptr_t)hEngines"] - - [ctf_sequence_text, uint8_t, pEngineStats_val, pEngineStats, size_t, "sizeof(zes_engine_stats_t)"] + - [lttng_ust_field_variable_length_blob, pEngineStats_val, pEngineStats, size_t, "sizeof(zes_engine_stats_t)", "application/octet-stream"] - name: powerProperties args: - [zes_device_handle_t, hDevice] @@ -35,7 +35,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hPowers, "(uintptr_t)hPowers"] - - [ctf_sequence_text, uint8_t, pPowerProperties_val, pPowerProperties, size_t, "sizeof(zes_power_properties_t)"] + - [lttng_ust_field_variable_length_blob, pPowerProperties_val, pPowerProperties, size_t, "sizeof(zes_power_properties_t)", "application/octet-stream"] - name: gpu_energy args: - [zes_device_handle_t, hDevice] @@ -46,7 +46,7 @@ lttng_ust_ze_sampling: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hPowers, "(uintptr_t)hPowers"] - [ctf_integer, uint32_t, domainIdx, "domainIdx"] - - [ctf_sequence_text, uint8_t, pEnergyCounter_val, pEnergyCounter, size_t, "sizeof(zes_power_energy_counter_t)"] + - [lttng_ust_field_variable_length_blob, pEnergyCounter_val, pEnergyCounter, size_t, "sizeof(zes_power_energy_counter_t)", "application/octet-stream"] - name: freqProperties args: - [zes_device_handle_t, hDevice] @@ -55,7 +55,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFrequency, "(uintptr_t)hFrequency"] - - [ctf_sequence_text, uint8_t, pFreqProperties_val, pFreqProperties, size_t, "sizeof(zes_freq_properties_t)"] + - [lttng_ust_field_variable_length_blob, pFreqProperties_val, pFreqProperties, size_t, "sizeof(zes_freq_properties_t)", "application/octet-stream"] - name: gpu_frequency args: - [zes_device_handle_t, hDevice] @@ -66,7 +66,7 @@ lttng_ust_ze_sampling: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFrequency, "(uintptr_t)hFrequency"] - [ctf_integer, uint32_t, domainIdx, "domainIdx"] - - [ctf_sequence_text, uint8_t, pFreqState_val, pFreqState, size_t, "sizeof(zes_freq_state_t)"] + - [lttng_ust_field_variable_length_blob, pFreqState_val, pFreqState, size_t, "sizeof(zes_freq_state_t)", "application/octet-stream"] - name: fabricPortProperties args: - [zes_device_handle_t, hDevice] @@ -75,7 +75,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFabricPort, "(uintptr_t)hFabricPort"] - - [ctf_sequence_text, uint8_t, pFabricPortProperties_val, pFabricPortProperties, size_t, "sizeof(zes_fabric_port_properties_t)"] + - [lttng_ust_field_variable_length_blob, pFabricPortProperties_val, pFabricPortProperties, size_t, "sizeof(zes_fabric_port_properties_t)", "application/octet-stream"] - name: fabricPort args: - [zes_device_handle_t, hDevice] @@ -85,8 +85,8 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFabricPort, "(uintptr_t)hFabricPort"] - - [ctf_sequence_text, uint8_t, pFabricPortState_val, pFabricPortState, size_t, "sizeof(zes_fabric_port_state_t)"] - - [ctf_sequence_text, uint8_t, pFabricPortThroughput_val, pFabricPortThroughput, size_t, "sizeof(zes_fabric_port_throughput_t)"] + - [lttng_ust_field_variable_length_blob, pFabricPortState_val, pFabricPortState, size_t, "sizeof(zes_fabric_port_state_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pFabricPortThroughput_val, pFabricPortThroughput, size_t, "sizeof(zes_fabric_port_throughput_t)", "application/octet-stream"] - name: memoryProperties args: - [zes_device_handle_t, hDevice] @@ -95,7 +95,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hMemModule, "(uintptr_t)hMemModule"] - - [ctf_sequence_text, uint8_t, pMemModuleProperties_val, pMemModuleProperties, size_t, "sizeof(zes_mem_properties_t)"] + - [lttng_ust_field_variable_length_blob, pMemModuleProperties_val, pMemModuleProperties, size_t, "sizeof(zes_mem_properties_t)", "application/octet-stream"] - name: memStats args: - [zes_device_handle_t, hDevice] @@ -105,8 +105,8 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hMemModule, "(uintptr_t)hMemModule"] - - [ctf_sequence_text, uint8_t, pMemState_val, pMemState, size_t, "sizeof(zes_mem_state_t)"] - - [ctf_sequence_text, uint8_t, pMemBandwidth_val, pMemBandwidth, size_t, "sizeof(zes_mem_bandwidth_t)"] + - [lttng_ust_field_variable_length_blob, pMemState_val, pMemState, size_t, "sizeof(zes_mem_state_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pMemBandwidth_val, pMemBandwidth, size_t, "sizeof(zes_mem_bandwidth_t)", "application/octet-stream"] lttng_ust_ze_profiling: events: - name: event_profiling @@ -139,7 +139,7 @@ lttng_ust_ze_properties: - [ze_driver_properties_t *, pDriverProperties] fields: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - - [ctf_sequence_text, uint8_t, pDriverProperties_val, pDriverProperties, size_t, "sizeof(ze_driver_properties_t)"] + - [lttng_ust_field_variable_length_blob, pDriverProperties_val, pDriverProperties, size_t, "sizeof(ze_driver_properties_t)", "application/octet-stream"] - name: device args: - [ze_driver_handle_t, hDriver] @@ -148,7 +148,7 @@ lttng_ust_ze_properties: fields: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - - [ctf_sequence_text, uint8_t, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)"] + - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)", "application/octet-stream"] - name: subdevice args: - [ze_driver_handle_t, hDriver] @@ -159,7 +159,7 @@ lttng_ust_ze_properties: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hSubDevice, "(uintptr_t)hSubDevice"] - - [ctf_sequence_text, uint8_t, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)"] + - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)", "application/octet-stream"] - name: command_queue_group args: - [ze_driver_handle_t, hDriver] @@ -170,7 +170,7 @@ lttng_ust_ze_properties: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer, uint32_t, pCount, pCount] - - [ctf_sequence_text, uint8_t, pGroupProperties_vals, pGroupProperties, size_t, "pCount * sizeof(ze_command_queue_group_properties_t)"] + - [lttng_ust_field_variable_length_blob, pGroupProperties_vals, pGroupProperties, size_t, "pCount * sizeof(ze_command_queue_group_properties_t)", "application/octet-stream"] - name: device_timer args: - [ze_device_handle_t, hDevice] @@ -189,7 +189,7 @@ lttng_ust_ze_properties: fields: - [ctf_integer_hex, uintptr_t, hContext, "(uintptr_t)hContext"] - [ctf_integer_hex, uintptr_t, ptr, "(uintptr_t)ptr"] - - [ctf_sequence_text, uint8_t, pMemAllocProperties_val, pMemAllocProperties, size_t, "sizeof(ze_memory_allocation_properties_t)"] + - [lttng_ust_field_variable_length_blob, pMemAllocProperties_val, pMemAllocProperties, size_t, "sizeof(ze_memory_allocation_properties_t)", "application/octet-stream"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - name: memory_info_range args: @@ -208,7 +208,7 @@ lttng_ust_ze_properties: - [ze_kernel_properties_t *, pKernelProperties] fields: - [ctf_integer_hex, uintptr_t, hKernel, "(uintptr_t)hKernel"] - - [ctf_sequence_text, uint8_t, pKernelProperties_val, pKernelProperties, size_t, "sizeof(ze_kernel_properties_t)"] + - [lttng_ust_field_variable_length_blob, pKernelProperties_val, pKernelProperties, size_t, "sizeof(ze_kernel_properties_t)", "application/octet-stream"] lttng_ust_ze_build: events: - name: log diff --git a/utils/LTTng.rb b/utils/LTTng.rb index 8bcce8385..40aaf74de 100644 --- a/utils/LTTng.rb +++ b/utils/LTTng.rb @@ -84,27 +84,9 @@ class TracepointField attr_accessor :macro, :expression, :type, :provider_name, :enum_name, :length, :length_type, :cast, :media_type attr_reader :name - # Rewrite a positional uint8_t text sequence/array (raw bytes recorded as - # "text") into the equivalent 2.16 blob macro. Genuine char text is left - # alone. Shape in: [ctf_sequence_text, uint8_t, name, expr, len_type, len] - # or: [ctf_array_text, uint8_t, name, expr, len] - def self.blobify(args) - return args unless args.length > 1 && %i[ctf_sequence_text ctf_array_text].include?(args[0].to_sym) - return args unless args[1].to_sym == :uint8_t - - rest = args[2..-1] - case args[0].to_sym - when :ctf_sequence_text - [:lttng_ust_field_variable_length_blob, *rest, DEFAULT_MEDIA_TYPE] - when :ctf_array_text - [:lttng_ust_field_fixed_length_blob, *rest, DEFAULT_MEDIA_TYPE] - end - end - def initialize(*args) return unless args.length > 0 - args = self.class.blobify(args) desc = FIELDS[args[0].to_sym] raise "Invalid field #{args[0]}!" unless desc diff --git a/utils/yaml_ast_lttng.rb b/utils/yaml_ast_lttng.rb index de4ffec80..b10d672cf 100644 --- a/utils/yaml_ast_lttng.rb +++ b/utils/yaml_ast_lttng.rb @@ -186,12 +186,14 @@ def lttng_type(type_classes, length: nil, length_type: nil) ev.macro = :"ctf_#{lttng_arr_type}" ev.type = :int32_t when :aggregate + # An element count times an element size. The array arm is only + # reached once a length is known -- a length-less array is logged as + # its address above -- so the total is always a run-time size_t, and + # the blob is always the variable-length one. + ev.macro = :lttng_ust_field_variable_length_blob ev.type = :uint8_t - if ev.length - ev.length = "(#{ev.length}) * sizeof(#{type.name})" - ev.length_type = 'size_t' - end - ev.macro = ev.length_type ? :lttng_ust_field_variable_length_blob : :lttng_ust_field_fixed_length_blob + ev.length = "(#{ev.length}) * sizeof(#{type.name})" + ev.length_type = 'size_t' else super(type_classes) end From e1470823811c78250dd90c9921280e65694c7c07 Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Mon, 21 Sep 2026 15:16:08 +0000 Subject: [PATCH 04/10] gen: run yamlfmt on the event files this branch edits These three predate the yamlfmt lint job and were never formatted. CI only lints CHANGED yaml, so editing them for the blob work is what makes them eligible -- the same way btx_tally_params.yaml surfaced. ze_events.yaml was already clean and stays clean. Pure reformatting: the parsed YAML is unchanged and all 49 generated files are byte-identical. Co-Authored-By: Claude Opus 5 (1M context) --- backends/cuda/cuda_events.yaml | 83 +++-- backends/opencl/opencl_events.yaml | 373 ++++++++++----------- backends/opencl/opencl_wrapper_events.yaml | 119 ++++--- 3 files changed, 286 insertions(+), 289 deletions(-) diff --git a/backends/cuda/cuda_events.yaml b/backends/cuda/cuda_events.yaml index 160170b13..3bbbd20d2 100644 --- a/backends/cuda/cuda_events.yaml +++ b/backends/cuda/cuda_events.yaml @@ -1,68 +1,67 @@ ---- lttng_ust_cuda_args: events: - name: arg_count args: - - [ CUfunction, f ] - - [ size_t, argCount ] + - [CUfunction, f] + - [size_t, argCount] fields: - - [ ctf_integer_hex, uintptr_t, f, "(uintptr_t)f" ] - - [ ctf_integer, size_t, argCount, argCount ] + - [ctf_integer_hex, uintptr_t, f, "(uintptr_t)f"] + - [ctf_integer, size_t, argCount, argCount] - name: arg_value args: - - [ CUfunction, f ] - - [ size_t, argIndex ] - - [ "void *", kernelParam ] - - [ size_t, argSize ] + - [CUfunction, f] + - [size_t, argIndex] + - ["void *", kernelParam] + - [size_t, argSize] fields: - - [ ctf_integer_hex, uintptr_t, f, "(uintptr_t)f" ] - - [ ctf_integer, size_t, argIndex, argIndex ] - - [ ctf_integer_hex, uintptr_t, kernelParam, "(uintptr_t)kernelParam" ] - - [ lttng_ust_field_variable_length_blob, kernelParam_val, "(uint8_t *)kernelParam", size_t, "kernelParam ? argSize : 0" , "application/octet-stream"] + - [ctf_integer_hex, uintptr_t, f, "(uintptr_t)f"] + - [ctf_integer, size_t, argIndex, argIndex] + - [ctf_integer_hex, uintptr_t, kernelParam, "(uintptr_t)kernelParam"] + - [lttng_ust_field_variable_length_blob, kernelParam_val, "(uint8_t *)kernelParam", size_t, "kernelParam ? argSize : 0", "application/octet-stream"] lttng_ust_cuda_profiling: events: - name: event_profiling args: - - [ CUevent, hStart ] - - [ CUevent, hStop ] + - [CUevent, hStart] + - [CUevent, hStop] fields: - - [ ctf_integer_hex, uintptr_t, hStart, "(uintptr_t)hStart" ] - - [ ctf_integer_hex, uintptr_t, hStop, "(uintptr_t)hStop" ] + - [ctf_integer_hex, uintptr_t, hStart, "(uintptr_t)hStart"] + - [ctf_integer_hex, uintptr_t, hStop, "(uintptr_t)hStop"] - name: event_profiling_results args: - - [ CUevent, hStart ] - - [ CUevent, hStop ] - - [ CUresult, startStatus ] - - [ CUresult, stopStatus ] - - [ CUresult, status ] - - [ float, milliseconds ] + - [CUevent, hStart] + - [CUevent, hStop] + - [CUresult, startStatus] + - [CUresult, stopStatus] + - [CUresult, status] + - [float, milliseconds] fields: - - [ ctf_integer_hex, uintptr_t, hStart, "(uintptr_t)hStart" ] - - [ ctf_integer_hex, uintptr_t, hStop, "(uintptr_t)hStop" ] - - [ ctf_integer, CUresult, startStatus, startStatus ] - - [ ctf_integer, CUresult, stopStatus, stopStatus ] - - [ ctf_integer, CUresult, status, status ] - - [ ctf_float, float, milliseconds, milliseconds ] + - [ctf_integer_hex, uintptr_t, hStart, "(uintptr_t)hStart"] + - [ctf_integer_hex, uintptr_t, hStop, "(uintptr_t)hStop"] + - [ctf_integer, CUresult, startStatus, startStatus] + - [ctf_integer, CUresult, stopStatus, stopStatus] + - [ctf_integer, CUresult, status, status] + - [ctf_float, float, milliseconds, milliseconds] lttng_ust_cuda_exports: events: - name: export_called args: - - [ CUuuid *, pExportTableId ] - - [ size_t, exportOffset ] + - [CUuuid *, pExportTableId] + - [size_t, exportOffset] fields: - - [ ctf_integer_hex, uintptr_t, pExportTableId, "(uintptr_t)pExportTableId" ] - - [ ctf_integer_hex, size_t, exportOffset, exportOffset ] - - [ lttng_ust_field_variable_length_blob, pExportTableId_val, pExportTableId, size_t, "sizeof(CUuuid)" , "application/octet-stream"] + - [ctf_integer_hex, uintptr_t, pExportTableId, "(uintptr_t)pExportTableId"] + - [ctf_integer_hex, size_t, exportOffset, exportOffset] + - [lttng_ust_field_variable_length_blob, pExportTableId_val, pExportTableId, size_t, "sizeof(CUuuid)", "application/octet-stream"] lttng_ust_cuda_properties: events: - name: device args: - - [ int, ordinal ] - - [ CUdevice , device ] - - [ char *, name ] - - [ CUuuid *, uuid ] + - [int, ordinal] + - [CUdevice, device] + - [char *, name] + - [CUuuid *, uuid] fields: - - [ ctf_integer, int, ordinal, ordinal ] - - [ ctf_integer_hex, int, device, device ] - - [ ctf_string, name, name ] - - [ lttng_ust_field_variable_length_blob, uuid, uuid, size_t, "sizeof(CUuuid)" , "application/octet-stream"] + - [ctf_integer, int, ordinal, ordinal] + - [ctf_integer_hex, int, device, device] + - [ctf_string, name, name] + - [lttng_ust_field_variable_length_blob, uuid, uuid, size_t, "sizeof(CUuuid)", "application/octet-stream"] diff --git a/backends/opencl/opencl_events.yaml b/backends/opencl/opencl_events.yaml index 32ebfd14c..a87a6ae4b 100644 --- a/backends/opencl/opencl_events.yaml +++ b/backends/opencl/opencl_events.yaml @@ -1,254 +1,253 @@ ---- lttng_ust_opencl_build: events: - name: objects args: - - [ cl_program, program ] - - [ cl_device_id, device ] - - [ size_t, size ] - - [ "char *", path ] + - [cl_program, program] + - [cl_device_id, device] + - [size_t, size] + - ["char *", path] fields: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, device, "(uintptr_t)device" ] - - [ ctf_integer, size_t, size, size ] - - [ ctf_string, path, path ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, device, "(uintptr_t)device"] + - [ctf_integer, size_t, size, size] + - [ctf_string, path, path] - name: binaries args: - - [ cl_program, program ] - - [ cl_device_id, device ] - - [ size_t, size ] - - [ "char *", path ] + - [cl_program, program] + - [cl_device_id, device] + - [size_t, size] + - ["char *", path] fields: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, device, "(uintptr_t)device" ] - - [ ctf_integer, size_t, size, size ] - - [ ctf_string, path, path ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, device, "(uintptr_t)device"] + - [ctf_integer, size_t, size, size] + - [ctf_string, path, path] - name: infos args: - - [ cl_program, program ] - - [ cl_device_id, device ] - - [ cl_build_status, build_status ] - - [ "char *", build_options ] - - [ "char *", build_log ] - fields: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, device, "(uintptr_t)device" ] - - [ ctf_integer, cl_build_status, build_status, build_status ] - - [ ctf_string, build_options, build_options ] - - [ ctf_string, build_log, build_log ] + - [cl_program, program] + - [cl_device_id, device] + - [cl_build_status, build_status] + - ["char *", build_options] + - ["char *", build_log] + fields: + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, device, "(uintptr_t)device"] + - [ctf_integer, cl_build_status, build_status, build_status] + - [ctf_string, build_options, build_options] + - [ctf_string, build_log, build_log] - name: infos_1_2 args: - - [ cl_program, program ] - - [ cl_device_id, device ] - - [ cl_program_binary_type, binary_type ] + - [cl_program, program] + - [cl_device_id, device] + - [cl_program_binary_type, binary_type] fields: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, device, "(uintptr_t)device" ] - - [ ctf_integer, cl_program_binary_type, binary_type, binary_type ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, device, "(uintptr_t)device"] + - [ctf_integer, cl_program_binary_type, binary_type, binary_type] - name: infos_2_0 args: - - [ cl_program, program ] - - [ cl_device_id, device ] - - [ size_t, build_global_variable_total_size ] + - [cl_program, program] + - [cl_device_id, device] + - [size_t, build_global_variable_total_size] fields: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, device, "(uintptr_t)device" ] - - [ ctf_integer, size_t, build_global_variable_total_size, build_global_variable_total_size ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, device, "(uintptr_t)device"] + - [ctf_integer, size_t, build_global_variable_total_size, build_global_variable_total_size] lttng_ust_opencl_arguments: events: - name: argument_info args: - - [ cl_kernel, kernel ] - - [ cl_uint, arg_index ] - - [ cl_kernel_arg_address_qualifier, address_qualifier ] - - [ cl_kernel_arg_access_qualifier, access_qualifier ] - - [ "char *", type_name ] - - [ cl_kernel_arg_type_qualifier, type_qualifier ] - - [ "char *", name ] - fields: - - [ ctf_integer_hex, uintptr_t, kernel, "(uintptr_t)kernel" ] - - [ ctf_integer, cl_uint, arg_index, arg_index ] - - [ ctf_integer, cl_kernel_arg_address_qualifier, address_qualifier, address_qualifier ] - - [ ctf_integer, cl_kernel_arg_access_qualifier, access_qualifier, access_qualifier ] - - [ ctf_string, type_name, type_name ] - - [ ctf_integer, cl_kernel_arg_type_qualifier, type_qualifier, type_qualifier ] - - [ ctf_string, name, name ] + - [cl_kernel, kernel] + - [cl_uint, arg_index] + - [cl_kernel_arg_address_qualifier, address_qualifier] + - [cl_kernel_arg_access_qualifier, access_qualifier] + - ["char *", type_name] + - [cl_kernel_arg_type_qualifier, type_qualifier] + - ["char *", name] + fields: + - [ctf_integer_hex, uintptr_t, kernel, "(uintptr_t)kernel"] + - [ctf_integer, cl_uint, arg_index, arg_index] + - [ctf_integer, cl_kernel_arg_address_qualifier, address_qualifier, address_qualifier] + - [ctf_integer, cl_kernel_arg_access_qualifier, access_qualifier, access_qualifier] + - [ctf_string, type_name, type_name] + - [ctf_integer, cl_kernel_arg_type_qualifier, type_qualifier, type_qualifier] + - [ctf_string, name, name] - name: kernel_info args: - - [ cl_kernel, kernel ] - - [ "char *", function_name ] - - [ cl_uint, num_args ] - - [ cl_context, context ] - - [ cl_program, program ] - - [ "char *", attibutes ] - fields: - - [ ctf_integer_hex, uintptr_t, kernel, "(uintptr_t)kernel" ] - - [ ctf_string, function_name, function_name ] - - [ ctf_integer, cl_uint, num_args, num_args ] - - [ ctf_integer_hex, uintptr_t, context, "(uintptr_t)context" ] - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_string, attibutes, attibutes ] + - [cl_kernel, kernel] + - ["char *", function_name] + - [cl_uint, num_args] + - [cl_context, context] + - [cl_program, program] + - ["char *", attibutes] + fields: + - [ctf_integer_hex, uintptr_t, kernel, "(uintptr_t)kernel"] + - [ctf_string, function_name, function_name] + - [ctf_integer, cl_uint, num_args, num_args] + - [ctf_integer_hex, uintptr_t, context, "(uintptr_t)context"] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_string, attibutes, attibutes] lttng_ust_opencl_dump: enums: - name: dump_enum values: - - [ ctf_enum_value, BEFORE, 0 ] - - [ ctf_enum_value, AFTER, 1 ] + - [ctf_enum_value, BEFORE, 0] + - [ctf_enum_value, AFTER, 1] events: - name: enqueue_counter args: - - [ uint64_t, enqueue_counter ] + - [uint64_t, enqueue_counter] fields: - - [ ctf_integer, uint64_t, enqueue_counter, enqueue_counter ] + - [ctf_integer, uint64_t, enqueue_counter, enqueue_counter] - name: kernel_arg_value args: - - [ uint64_t, enqueue_counter ] - - [ cl_uint, arg_index ] - - [ size_t, arg_size ] - - [ "void *", arg_value ] + - [uint64_t, enqueue_counter] + - [cl_uint, arg_index] + - [size_t, arg_size] + - ["void *", arg_value] fields: - - [ ctf_integer, uint64_t, enqueue_counter, enqueue_counter ] - - [ ctf_integer, cl_uint, arg_index, arg_index ] - - [ ctf_integer, size_t, arg_size, arg_size ] - - [ lttng_ust_field_variable_length_blob, arg_value, arg_value, size_t, "arg_value == NULL ? 0 : arg_size" , "application/octet-stream"] + - [ctf_integer, uint64_t, enqueue_counter, enqueue_counter] + - [ctf_integer, cl_uint, arg_index, arg_index] + - [ctf_integer, size_t, arg_size, arg_size] + - [lttng_ust_field_variable_length_blob, arg_value, arg_value, size_t, "arg_value == NULL ? 0 : arg_size", "application/octet-stream"] - name: svmptr_dump_event args: - - [ uint64_t, enqueue_counter ] - - [ cl_uint, arg_index ] - - [ int, direction ] - - [ "void *", buffer ] - - [ int, status ] - - [ cl_event, event ] - fields: - - [ ctf_integer, uint64_t, enqueue_counter, enqueue_counter ] - - [ ctf_integer, cl_uint, arg_index, arg_index ] - - [ ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction ] - - [ ctf_integer_hex, uintptr_t, buffer, "(uintptr_t)buffer" ] - - [ ctf_integer, int, status, status ] - - [ ctf_integer_hex, uintptr_t, event, "(uintptr_t)event" ] + - [uint64_t, enqueue_counter] + - [cl_uint, arg_index] + - [int, direction] + - ["void *", buffer] + - [int, status] + - [cl_event, event] + fields: + - [ctf_integer, uint64_t, enqueue_counter, enqueue_counter] + - [ctf_integer, cl_uint, arg_index, arg_index] + - [ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction] + - [ctf_integer_hex, uintptr_t, buffer, "(uintptr_t)buffer"] + - [ctf_integer, int, status, status] + - [ctf_integer_hex, uintptr_t, event, "(uintptr_t)event"] - name: svmptr_dump_result args: - - [ uint64_t, enqueue_counter ] - - [ cl_uint, arg_index ] - - [ int, direction ] - - [ cl_event, event ] - - [ cl_int, status ] - - [ size_t, size ] - - [ "char *", path ] - fields: - - [ ctf_integer, uint64_t, enqueue_counter, enqueue_counter ] - - [ ctf_integer, cl_uint, arg_index, arg_index ] - - [ ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction ] - - [ ctf_integer_hex, uintptr_t, event, "(uintptr_t)event" ] - - [ ctf_integer, int, status, status ] - - [ ctf_integer, size_t, size, size ] - - [ ctf_string, path, path ] + - [uint64_t, enqueue_counter] + - [cl_uint, arg_index] + - [int, direction] + - [cl_event, event] + - [cl_int, status] + - [size_t, size] + - ["char *", path] + fields: + - [ctf_integer, uint64_t, enqueue_counter, enqueue_counter] + - [ctf_integer, cl_uint, arg_index, arg_index] + - [ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction] + - [ctf_integer_hex, uintptr_t, event, "(uintptr_t)event"] + - [ctf_integer, int, status, status] + - [ctf_integer, size_t, size, size] + - [ctf_string, path, path] - name: buffer_dump_event args: - - [ uint64_t, enqueue_counter ] - - [ cl_uint, arg_index ] - - [ int, direction ] - - [ cl_mem, buffer ] - - [ int, status ] - - [ cl_event, event ] - fields: - - [ ctf_integer, uint64_t, enqueue_counter, enqueue_counter ] - - [ ctf_integer, cl_uint, arg_index, arg_index ] - - [ ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction ] - - [ ctf_integer_hex, uintptr_t, buffer, "(uintptr_t)buffer" ] - - [ ctf_integer, int, status, status ] - - [ ctf_integer_hex, uintptr_t, event, "(uintptr_t)event" ] + - [uint64_t, enqueue_counter] + - [cl_uint, arg_index] + - [int, direction] + - [cl_mem, buffer] + - [int, status] + - [cl_event, event] + fields: + - [ctf_integer, uint64_t, enqueue_counter, enqueue_counter] + - [ctf_integer, cl_uint, arg_index, arg_index] + - [ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction] + - [ctf_integer_hex, uintptr_t, buffer, "(uintptr_t)buffer"] + - [ctf_integer, int, status, status] + - [ctf_integer_hex, uintptr_t, event, "(uintptr_t)event"] - name: buffer_dump_result args: - - [ uint64_t, enqueue_counter ] - - [ cl_uint, arg_index ] - - [ int, direction ] - - [ cl_event, event ] - - [ cl_int, status ] - - [ size_t, size ] - - [ "char *", path ] - fields: - - [ ctf_integer, uint64_t, enqueue_counter, enqueue_counter ] - - [ ctf_integer, cl_uint, arg_index, arg_index ] - - [ ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction ] - - [ ctf_integer_hex, uintptr_t, event, "(uintptr_t)event" ] - - [ ctf_integer, int, status, status ] - - [ ctf_integer, size_t, size, size ] - - [ ctf_string, path, path ] + - [uint64_t, enqueue_counter] + - [cl_uint, arg_index] + - [int, direction] + - [cl_event, event] + - [cl_int, status] + - [size_t, size] + - ["char *", path] + fields: + - [ctf_integer, uint64_t, enqueue_counter, enqueue_counter] + - [ctf_integer, cl_uint, arg_index, arg_index] + - [ctf_enum, lttng_ust_opencl_dump, dump_enum, int, direction, direction] + - [ctf_integer_hex, uintptr_t, event, "(uintptr_t)event"] + - [ctf_integer, int, status, status] + - [ctf_integer, size_t, size, size] + - [ctf_string, path, path] lttng_ust_opencl_profiling: events: - name: event_profiling args: - - [ int, status ] - - [ cl_event, event ] + - [int, status] + - [cl_event, event] fields: - - [ ctf_integer, int, status, status ] - - [ ctf_integer_hex, uintptr_t, event, "(uintptr_t)event" ] + - [ctf_integer, int, status, status] + - [ctf_integer_hex, uintptr_t, event, "(uintptr_t)event"] - name: event_profiling_results args: - - [ cl_event, event ] - - [ cl_int, event_command_exec_status ] - - [ cl_int, queued_status ] - - [ cl_ulong, queued ] - - [ cl_int, submit_status ] - - [ cl_ulong, submit ] - - [ cl_int, start_status ] - - [ cl_ulong, start ] - - [ cl_int, end_status ] - - [ cl_ulong, end ] - fields: - - [ ctf_integer_hex, uintptr_t, event, "(uintptr_t)event" ] - - [ ctf_integer, int, event_command_exec_status, event_command_exec_status ] - - [ ctf_integer, cl_int, queued_status, queued_status ] - - [ ctf_integer, cl_ulong, queued, queued ] - - [ ctf_integer, cl_int, submit_status, submit_status ] - - [ ctf_integer, cl_ulong, submit, submit ] - - [ ctf_integer, cl_int, start_status, start_status ] - - [ ctf_integer, cl_ulong, start, start ] - - [ ctf_integer, cl_int, end_status, end_status ] - - [ ctf_integer, cl_ulong, end, end ] + - [cl_event, event] + - [cl_int, event_command_exec_status] + - [cl_int, queued_status] + - [cl_ulong, queued] + - [cl_int, submit_status] + - [cl_ulong, submit] + - [cl_int, start_status] + - [cl_ulong, start] + - [cl_int, end_status] + - [cl_ulong, end] + fields: + - [ctf_integer_hex, uintptr_t, event, "(uintptr_t)event"] + - [ctf_integer, int, event_command_exec_status, event_command_exec_status] + - [ctf_integer, cl_int, queued_status, queued_status] + - [ctf_integer, cl_ulong, queued, queued] + - [ctf_integer, cl_int, submit_status, submit_status] + - [ctf_integer, cl_ulong, submit, submit] + - [ctf_integer, cl_int, start_status, start_status] + - [ctf_integer, cl_ulong, start, start] + - [ctf_integer, cl_int, end_status, end_status] + - [ctf_integer, cl_ulong, end, end] lttng_ust_opencl_source: events: - name: program_string args: - - [ int, index ] - - [ size_t , length ] - - [ "char *", path ] + - [int, index] + - [size_t, length] + - ["char *", path] fields: - - [ ctf_integer, int, index, index ] - - [ ctf_integer, size_t, length, length ] - - [ ctf_string, path, path ] + - [ctf_integer, int, index, index] + - [ctf_integer, size_t, length, length] + - [ctf_string, path, path] - name: program_binary args: - - [ int, index ] - - [ size_t , length ] - - [ char *, path ] + - [int, index] + - [size_t, length] + - [char *, path] fields: - - [ ctf_integer, int, index, index ] - - [ ctf_integer, size_t, length, length ] - - [ ctf_string, path, path ] + - [ctf_integer, int, index, index] + - [ctf_integer, size_t, length, length] + - [ctf_string, path, path] - name: program_il args: - - [ size_t, length ] - - [ "char *", path ] + - [size_t, length] + - ["char *", path] fields: - - [ ctf_integer, size_t, length, length ] - - [ ctf_string, path, path ] + - [ctf_integer, size_t, length, length] + - [ctf_string, path, path] lttng_ust_opencl_devices: events: - name: device_name args: - - [ cl_device_id, device] - - [ "char *", name ] + - [cl_device_id, device] + - ["char *", name] fields: - - [ ctf_integer_hex, uintptr_t, device, "(uintptr_t)device" ] - - [ ctf_string, name, name ] + - [ctf_integer_hex, uintptr_t, device, "(uintptr_t)device"] + - [ctf_string, name, name] - name: device_timer args: - - [ cl_device_id, device ] - - [ cl_ulong, device_timestamp ] - - [ cl_ulong, host_timestamp ] + - [cl_device_id, device] + - [cl_ulong, device_timestamp] + - [cl_ulong, host_timestamp] fields: - - [ ctf_integer_hex, uintptr_t, device, "(uintptr_t)device" ] - - [ ctf_integer, cl_ulong, device_timestamp, device_timestamp ] - - [ ctf_integer, cl_ulong, host_timestamp, host_timestamp ] + - [ctf_integer_hex, uintptr_t, device, "(uintptr_t)device"] + - [ctf_integer, cl_ulong, device_timestamp, device_timestamp] + - [ctf_integer, cl_ulong, host_timestamp, host_timestamp] diff --git a/backends/opencl/opencl_wrapper_events.yaml b/backends/opencl/opencl_wrapper_events.yaml index fc4c1ddb1..c166320bd 100644 --- a/backends/opencl/opencl_wrapper_events.yaml +++ b/backends/opencl/opencl_wrapper_events.yaml @@ -1,92 +1,91 @@ ---- lttng_ust_opencl: events: - name: clBuildProgram_callback args: - - [ cl_program, program ] - - [ "void *", user_data ] + - [cl_program, program] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - name: clCompileProgram_callback args: - - [ cl_program, program ] - - [ "void *", user_data ] + - [cl_program, program] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - name: clLinkProgram_callback args: - - [ cl_program, program ] - - [ "void *", user_data ] + - [cl_program, program] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - name: clCreateContext_callback args: - - [ "const char *", errinfo ] - - [ "const void *", private_info ] - - [ size_t, cb, ] - - [ "void *", user_data ] + - ["const char *", errinfo] + - ["const void *", private_info] + - [size_t, cb] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, errinfo, "(uintptr_t)errinfo" ] - - [ ctf_integer_hex, uintptr_t, private_info, "(uintptr_t)private_info" ] - - [ ctf_integer, size_t, cb, cb ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] - - [ ctf_string, errinfo_val, errinfo ] - - [ lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" , "application/octet-stream"] + - [ctf_integer_hex, uintptr_t, errinfo, "(uintptr_t)errinfo"] + - [ctf_integer_hex, uintptr_t, private_info, "(uintptr_t)private_info"] + - [ctf_integer, size_t, cb, cb] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] + - [ctf_string, errinfo_val, errinfo] + - [lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)", "application/octet-stream"] - name: clCreateContextFromType_callback args: - - [ "const char *", errinfo ] - - [ "const void *", private_info ] - - [ size_t, cb, ] - - [ "void *", user_data ] + - ["const char *", errinfo] + - ["const void *", private_info] + - [size_t, cb] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, errinfo, "(uintptr_t)errinfo" ] - - [ ctf_integer_hex, uintptr_t, private_info, "(uintptr_t)private_info" ] - - [ ctf_integer, size_t, cb, cb ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] - - [ ctf_string, errinfo_val, errinfo ] - - [ lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" , "application/octet-stream"] + - [ctf_integer_hex, uintptr_t, errinfo, "(uintptr_t)errinfo"] + - [ctf_integer_hex, uintptr_t, private_info, "(uintptr_t)private_info"] + - [ctf_integer, size_t, cb, cb] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] + - [ctf_string, errinfo_val, errinfo] + - [lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)", "application/octet-stream"] - name: clSetMemObjectDestructorCallback_callback args: - - [ cl_mem, memobj ] - - [ "void *", user_data ] + - [cl_mem, memobj] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, memobj, "(uintptr_t)memobj" ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] + - [ctf_integer_hex, uintptr_t, memobj, "(uintptr_t)memobj"] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - name: clSetProgramReleaseCallback_callback args: - - [ cl_program, program ] - - [ "void *", user_data ] + - [cl_program, program] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, program, "(uintptr_t)program" ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] + - [ctf_integer_hex, uintptr_t, program, "(uintptr_t)program"] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - name: clSetEventCallback_callback args: - - [ cl_event, event ] - - [ cl_int, type ] - - [ "void *", user_data ] + - [cl_event, event] + - [cl_int, type] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, event, "(uintptr_t)event" ] - - [ ctf_integer, cl_int, type, type ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] + - [ctf_integer_hex, uintptr_t, event, "(uintptr_t)event"] + - [ctf_integer, cl_int, type, type] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - name: clEnqueueSVMFree_callback args: - - [ cl_command_queue, command_queue ] - - [ cl_uint, num_svm_pointers ] - - [ "void **", svm_pointers ] - - [ "void *", user_data ] + - [cl_command_queue, command_queue] + - [cl_uint, num_svm_pointers] + - ["void **", svm_pointers] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, command_queue, "(uintptr_t)command_queue" ] - - [ ctf_integer, cl_uint, num_svm_pointers, num_svm_pointers ] - - [ ctf_integer_hex, uintptr_t, svm_pointers, "(uintptr_t)svm_pointers" ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] - - [ ctf_sequence_hex, uintptr_t, svm_pointers_vals, svm_pointers, cl_uint, "svm_pointers ? num_svm_pointers : 0" ] + - [ctf_integer_hex, uintptr_t, command_queue, "(uintptr_t)command_queue"] + - [ctf_integer, cl_uint, num_svm_pointers, num_svm_pointers] + - [ctf_integer_hex, uintptr_t, svm_pointers, "(uintptr_t)svm_pointers"] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] + - [ctf_sequence_hex, uintptr_t, svm_pointers_vals, svm_pointers, cl_uint, "svm_pointers ? num_svm_pointers : 0"] - name: clSetContextDestructorCallback_callback args: - - [ cl_context, context ] - - [ "void *", user_data ] + - [cl_context, context] + - ["void *", user_data] start: - - [ ctf_integer_hex, uintptr_t, context, "(uintptr_t)context" ] - - [ ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data" ] + - [ctf_integer_hex, uintptr_t, context, "(uintptr_t)context"] + - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] From 7a269995643c97a5a123f2d870d2e4e6c61b05b1 Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Mon, 21 Sep 2026 15:41:23 +0000 Subject: [PATCH 05/10] gen: drop cast_type_is_struct, which nothing reads any more metababel consults this flag in exactly one place: BTFieldClass::String's setter and getter, where it means "the C variable is a struct by value, so memcpy into it rather than treating it as a char*". That is why the AST side refused to set it on a cast_type ending in `*`, under a comment admitting nobody knew why struct_names alone was not enough -- a pointer is not a struct by value, so the memcpy would have been wrong. Recording raw bytes as blobs removed the only reason it existed. All 62 fields carrying the flag are now blob_static or blob_dynamic, and the blob field classes never look at it: the static one always memcpys from `&variable`, the dynamic one from the pointer. metababel's own comment says the static blob "mirrors BTFieldClass::String with cast_type_is_struct". So THAPI was writing a flag no reader consults. That also explains a divergence: opencl set it on 11 fields whose cast_type ends in `*`, which the AST rule forbids, with no effect either way. Removing it settles the disagreement by deleting the question, and name_packed_struct no longer needs the field hash at all. All 36 generated .c files are byte-identical. Six model yamls change by exactly one thing: the key is gone. Co-Authored-By: Claude Opus 5 (1M context) --- backends/opencl/gen_babeltrace_cl_model.rb | 5 +---- utils/gen_babeltrace_model_helper.rb | 14 +++----------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/backends/opencl/gen_babeltrace_cl_model.rb b/backends/opencl/gen_babeltrace_cl_model.rb index b98d3d229..46b7189b8 100644 --- a/backends/opencl/gen_babeltrace_cl_model.rb +++ b/backends/opencl/gen_babeltrace_cl_model.rb @@ -59,10 +59,7 @@ def parse_field(field) when 'lttng_ust_field_variable_length_blob' d[:field_class][:type] = 'blob_dynamic' d[:field_class][:length_field_location] = payload_length_field_location(field['name']) - if field['structure'] - d[:field_class][:cast_type_is_struct] = true - d[:metadata] = { be_class: cl_to_class(field['type']) } - end + d[:metadata] = { be_class: cl_to_class(field['type']) } if field['structure'] when 'ctf_array' d[:field_class][:type] = 'array_static' d_field = parse_field({ 'lttng' => 'ctf_integer', 'type' => field['type'], 'pointer' => field['pointer'] }) diff --git a/utils/gen_babeltrace_model_helper.rb b/utils/gen_babeltrace_model_helper.rb index 7bc15549f..ea00c6dd9 100644 --- a/utils/gen_babeltrace_model_helper.rb +++ b/utils/gen_babeltrace_model_helper.rb @@ -71,19 +71,11 @@ def element_field_class(registry, lttng, lttng_name) # Raw bytes -- whether recorded as text or as a blob -- may really be a struct. # Resolve the typedef chain to its underlying name, and when that names a struct # say which FFI class reads it back. -def name_packed_struct(registry, field, member, type) +def name_packed_struct(registry, member, type) types_by_name = registry.types_by_name t = type.sub(' *', '') t = types_by_name[t].type.name while types_by_name.include?(t) && types_by_name[t].type.is_a?(YAMLCAst::CustomType) member[:metadata] = { be_class: registry.class_namer.call(t) } if registry.struct_names.include?(t) - - # Too complicated, not sure why `struct_names` is not enough - return if field[:cast_type].end_with?('*') - - packed = registry.struct_names.include?(t) || - types_by_name[t]&.type.is_a?(YAMLCAst::Union) || - type.start_with?('struct') - field[:cast_type_is_struct] = true if packed end def gen_bt_field_model(registry, lttng_name, type, name, lttng) @@ -120,7 +112,7 @@ def gen_bt_field_model(registry, lttng_name, type, name, lttng) when 'ctf_string', 'ctf_sequence_text', 'ctf_array_text' # Genuine text: char strings and char sequences/arrays. field[:type] = 'string' - name_packed_struct(registry, field, member, type) + name_packed_struct(registry, member, type) when 'lttng_ust_field_fixed_length_blob', 'lttng_ust_field_variable_length_blob' # Raw bytes -- a struct, a union, or an opaque buffer. A fixed-length blob # knows its size; a variable-length one reads it from the companion length @@ -133,7 +125,7 @@ def gen_bt_field_model(registry, lttng_name, type, name, lttng) field[:length_field_location] = payload_length_field_location(name) end field[:media_type] = lttng.media_type if lttng.media_type - name_packed_struct(registry, field, member, type) + name_packed_struct(registry, member, type) else raise "unsupported lttng type: #{lttng.inspect}" end From a8d241480f3897ff97ed7910c3863d9e6a10893a Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Mon, 21 Sep 2026 22:47:39 +0000 Subject: [PATCH 06/10] ci: build the 2.16 stack, which needs no work-around patches THAPI records raw bytes as lttng-ust 2.16 BLOB fields from this branch on, so the two halves of the old work-around are gone: `55cca69.diff`, which made lttng-ust write an array of text in full rather than stopping at the first NUL, and babeltrace's null-character patch, which let the reader run past that NUL. Neither is wanted now, and the babeltrace one is actively wrong on a blob-era build -- it makes a genuine ctf_string read past its terminator. lttng-tools and babeltrace still come from the ANL branches, since those carry the pause/resume commands and the archive component class that upstream does not have; they are simply rebased onto 2.16.0 and 2.1.2. The anl-ms3-v2.1.2 branch also carries the fix for the crash behind `# TODO use anl-ms3-v2.1.2 when ctf.archive.reader doesn't segfault anymore`, so that comment goes with it, and Simon Marchi's `Use LTTNGCTL_CFLAGS`, so CI no longer downloads that patch from a pinned THAPI commit. devel pins metababel to 1.x because it emits the MIP-0 `length_field_path`. This branch is what lifts that: configure.ac requires 2.0.0, so the plain package name resolves to what it needs. babeltrace_thapi resolved `source.ctf.lttng-archive` on every invocation, which fails on a build without archive support: that component class is an ANL addition, and `~archive` links a plain babeltrace2. Resolve it only when a graph names it. Co-Authored-By: Claude Opus 5 (1M context) --- .github/actions/setup-thapi/action.yml | 21 ++++----------------- utils/babeltrace_thapi.in | 10 +++++++++- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/.github/actions/setup-thapi/action.yml b/.github/actions/setup-thapi/action.yml index b0680b167..5796c1523 100644 --- a/.github/actions/setup-thapi/action.yml +++ b/.github/actions/setup-thapi/action.yml @@ -42,11 +42,7 @@ runs: packages: gcc g++ ruby ruby-dev elfutils libelf-dev libpopt-dev libdw-dev libprotobuf-dev protobuf-compiler valgrind libc6-dbg libglib2.0-dev libnuma-dev llvm-dev - name: Install Ruby Dependencies shell: bash - # metababel 2.0.0 is a breaking release: it replaced the MIP-0 - # `length_field_path` this branch emits with a MIP-1 field location. Pin to - # the series matching configure.ac's `metababel >= 1.1.3` until THAPI moves - # to MIP 1. - run: sudo gem install nokogiri babeltrace2 opencl_ruby_ffi 'metababel:~> 1.1' cast-to-yaml + run: sudo gem install nokogiri babeltrace2 opencl_ruby_ffi metababel cast-to-yaml - name: Set PKG_CONFIG shell: bash run: | @@ -70,10 +66,8 @@ runs: shell: bash if: steps.efficios_dep.outputs.cache-hit != 'true' run: | - git clone https://github.com/lttng/lttng-ust -b v2.14.0 + git clone https://github.com/lttng/lttng-ust -b v2.16.0 cd lttng-ust - wget https://raw.githubusercontent.com/argonne-lcf/THAPI-spack/a57eb4fa1b2b8621bb0e83a6ec25e48e3a761d15/packages/lttng-ust/55cca69.diff - patch -p1 < 55cca69.diff ./bootstrap ./configure --disable-man-pages --prefix=$HOME/efficios_dep/ make -j$(nproc) @@ -82,7 +76,7 @@ runs: shell: bash if: steps.efficios_dep.outputs.cache-hit != 'true' run: | - git clone https://github.com/argonne-lcf/lttng-tools.git -b anl-v2.14.0 + git clone https://github.com/argonne-lcf/lttng-tools.git -b anl-v2.16.0 cd lttng-tools ./bootstrap ./configure --disable-man-pages --disable-bin-lttng-crash --prefix=$HOME/efficios_dep @@ -92,15 +86,8 @@ runs: shell: bash if: steps.efficios_dep.outputs.cache-hit != 'true' run: | - git clone https://github.com/argonne-lcf/babeltrace.git -b anl-ms3 - # TODO use anl-ms3-v2.1.2 when ctf.archive.reader doesn't segfault anymore + git clone https://github.com/argonne-lcf/babeltrace.git -b anl-ms3-v2.1.2 cd babeltrace - # Fix include path - wget https://raw.githubusercontent.com/argonne-lcf/THAPI/4418916620496fd66cde0b3d5e241bed0a4c18a3/.github/workflows/bt_makefile.patch - patch -p1 < bt_makefile.patch - # Null char - wget https://raw.githubusercontent.com/argonne-lcf/THAPI-spack/ddc9a12a498331a7c312941df0d4e7078d03ae93/packages/babeltrace2/0001-Prevent-null-character-from-stopping-string-decoding.patch - patch -p1 < 0001-Prevent-null-character-from-stopping-string-decoding.patch ./bootstrap ./configure --disable-man-pages --prefix=$HOME/efficios_dep make -j$(nproc) diff --git a/utils/babeltrace_thapi.in b/utils/babeltrace_thapi.in index c86760df6..828896c44 100755 --- a/utils/babeltrace_thapi.in +++ b/utils/babeltrace_thapi.in @@ -132,13 +132,21 @@ def get_components(names) components_classes = { 'source.ctf.fs' => BT2::BTPlugin.find('ctf').get_source_component_class_by_name('fs'), 'source.ctf.lttng_live' => BT2::BTPlugin.find('ctf').get_source_component_class_by_name('lttng-live'), - 'source.ctf.lttng_archive' => BT2::BTPlugin.find('ctf').get_source_component_class_by_name('lttng-archive'), 'filter.utils.muxer' => BT2::BTPlugin.find('utils').get_filter_component_class_by_name('muxer'), 'sink.text.pretty' => BT2::BTPlugin.find('text').get_sink_component_class_by_name('pretty'), 'sink.ctf.fs' => BT2::BTPlugin.find('ctf').get_sink_component_class_by_name('fs'), 'sink.utils.dummy' => BT2::BTPlugin.find('utils').get_sink_component_class_by_name('dummy'), } + # `lttng-archive` is an ANL addition rather than an upstream component class, + # and a build without archive support links a plain babeltrace2 that does not + # have it. Resolve it only when a graph actually names it, so every other + # mode keeps working. + if names.include?('source.ctf.lttng_archive') + components_classes['source.ctf.lttng_archive'] = + BT2::BTPlugin.find('ctf').get_source_component_class_by_name('lttng-archive') + end + # THAPI components thapi_plugins = BT2::BTPlugin.find_all_from_dir(File.join('@prefix@', 'lib', '@PACKAGE@', 'bt2')) thapi_plugins.map do |pg| From a544a16fbce6ab86c6f833a44b606e1619412b3a Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Mon, 21 Sep 2026 23:12:44 +0000 Subject: [PATCH 07/10] ci: build babeltrace2-ruby from source, which the published gem predates The `iprof_fs` integration test fails while reading a trace: field.rb:19:in `from_handle': unsupported field class type (RuntimeError) babeltrace2-ruby's published gem is 0.1.5, from March 2025. BLOB support was added to the project in July 2026 and has not been released, so the gem CI installs has no entry in its field-class table for the blob fields THAPI now writes, and the pretty-printer raises on the first one. Build it from the repository until a release carries those commits. That also picks up the fix for a zero-length blob, which THAPI produces whenever it traces a null pointer to a struct -- clinfo alone emits 175. Co-Authored-By: Claude Opus 5 (1M context) --- .github/actions/setup-thapi/action.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup-thapi/action.yml b/.github/actions/setup-thapi/action.yml index 5796c1523..c0cf7da91 100644 --- a/.github/actions/setup-thapi/action.yml +++ b/.github/actions/setup-thapi/action.yml @@ -42,7 +42,17 @@ runs: packages: gcc g++ ruby ruby-dev elfutils libelf-dev libpopt-dev libdw-dev libprotobuf-dev protobuf-compiler valgrind libc6-dbg libglib2.0-dev libnuma-dev llvm-dev - name: Install Ruby Dependencies shell: bash - run: sudo gem install nokogiri babeltrace2 opencl_ruby_ffi metababel cast-to-yaml + run: sudo gem install nokogiri opencl_ruby_ffi metababel cast-to-yaml + - name: Install babeltrace2-ruby + shell: bash + # The published gem (0.1.5) predates BLOB support, so it cannot read the + # traces THAPI now writes. Build it from the branch until a release + # carries those commits. + run: | + git clone --depth 1 https://github.com/argonne-lcf/babeltrace2-ruby.git + cd babeltrace2-ruby + gem build babeltrace2.gemspec + sudo gem install --local ./babeltrace2-*.gem - name: Set PKG_CONFIG shell: bash run: | From 48b63183725040be61d907070ccb1f8e474a380a Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Thu, 24 Sep 2026 22:57:22 +0000 Subject: [PATCH 08/10] gen: derive a blob's media type from the type it records A blob field carried "application/octet-stream" no matter what it held, so a reader could not tell one struct's bytes from another's. The 45 rows that set it said the same thing 45 times, and the media type was a positional slot, so nothing failed when a caller filled it wrongly. Derive it instead. The type a blob records is already in reach on every path: the declared events name it in the same row's `args`, the AST knows the declaration it came from, and a hand-written meta-parameter resolves `command[name]`, which its constructor already fetched and discarded. Only `blob_type=` supplies it, and one rule spells it: x86-64/zes_device_properties_t a blob of one C type application/octet-stream `void *`, which names no type The 55 rows that keep the default are the attribute queries whose length is a conditional -- their bytes really are untyped -- so the fallback is the right answer there, not a gap. Three things fall out of removing the slot. OutLTTng and InLTTng had the same constructor twice; they now share LTTngMetaParameter, the base the file's five other meta-parameter kinds already had. print_struct_tracepoint hand-spelled a whole TRACEPOINT_EVENT, media type included, and now calls LTTng.print_tracepoint. And the model helper's argument lookup moved to LTTng.argument_type, which the tracepoint side needs too. That last one was not cosmetic: the two sides had been deriving the type separately, and the model side never set it for declared events. Folding them corrects 21 media types -- 19 in ze, 2 in cuda -- that disagreed with what the tracepoint wrote. The opencl model generator never emitted media_type at all. It has the C type in hand, so it now calls the same rule. No output changes but the media type: 27 generated files differ, none by anything else. 849 blob rows in the tracepoint providers, 794 typed; 818 in the models, 763 typed. Co-Authored-By: Claude Opus 5 --- backends/cuda/cuda_events.yaml | 6 ++-- backends/cuda/cuda_meta_parameters.yaml | 22 ++++++------ backends/hip/hip_meta_parameters.yaml | 18 +++++----- backends/opencl/gen_babeltrace_cl_model.rb | 1 + backends/opencl/opencl_events.yaml | 2 +- backends/opencl/opencl_model.rb | 10 ++---- backends/opencl/opencl_wrapper_events.yaml | 4 +-- backends/ze/gen_babeltrace_ze_model.rb | 3 +- backends/ze/ze_events.yaml | 38 ++++++++++---------- utils/LTTng.rb | 41 ++++++++++++++++++---- utils/gen_babeltrace_model_helper.rb | 5 +-- utils/gen_probe_base.rb | 23 +++++------- utils/meta_parameters.rb | 31 +++++++++------- utils/yaml_ast_lttng.rb | 4 +++ 14 files changed, 121 insertions(+), 87 deletions(-) diff --git a/backends/cuda/cuda_events.yaml b/backends/cuda/cuda_events.yaml index 3bbbd20d2..ca47a8c43 100644 --- a/backends/cuda/cuda_events.yaml +++ b/backends/cuda/cuda_events.yaml @@ -17,7 +17,7 @@ lttng_ust_cuda_args: - [ctf_integer_hex, uintptr_t, f, "(uintptr_t)f"] - [ctf_integer, size_t, argIndex, argIndex] - [ctf_integer_hex, uintptr_t, kernelParam, "(uintptr_t)kernelParam"] - - [lttng_ust_field_variable_length_blob, kernelParam_val, "(uint8_t *)kernelParam", size_t, "kernelParam ? argSize : 0", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, kernelParam_val, "(uint8_t *)kernelParam", size_t, "kernelParam ? argSize : 0"] lttng_ust_cuda_profiling: events: - name: event_profiling @@ -51,7 +51,7 @@ lttng_ust_cuda_exports: fields: - [ctf_integer_hex, uintptr_t, pExportTableId, "(uintptr_t)pExportTableId"] - [ctf_integer_hex, size_t, exportOffset, exportOffset] - - [lttng_ust_field_variable_length_blob, pExportTableId_val, pExportTableId, size_t, "sizeof(CUuuid)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pExportTableId_val, pExportTableId, size_t, "sizeof(CUuuid)"] lttng_ust_cuda_properties: events: - name: device @@ -64,4 +64,4 @@ lttng_ust_cuda_properties: - [ctf_integer, int, ordinal, ordinal] - [ctf_integer_hex, int, device, device] - [ctf_string, name, name] - - [lttng_ust_field_variable_length_blob, uuid, uuid, size_t, "sizeof(CUuuid)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, uuid, uuid, size_t, "sizeof(CUuuid)"] diff --git a/backends/cuda/cuda_meta_parameters.yaml b/backends/cuda/cuda_meta_parameters.yaml index de00b8ce3..7f800adb0 100644 --- a/backends/cuda/cuda_meta_parameters.yaml +++ b/backends/cuda/cuda_meta_parameters.yaml @@ -295,7 +295,7 @@ meta_parameters: cuMipmappedArrayGetLevel: - [OutScalar, pLevelArray] cuMemGetHandleForAddressRange: - - [OutLTTng, handle, lttng_ust_field_variable_length_blob, handle_val, handle, size_t, "handleType == CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD ? sizeof(int) : 0", "application/octet-stream"] + - [OutLTTng, handle, lttng_ust_field_variable_length_blob, handle_val, handle, size_t, "handleType == CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD ? sizeof(int) : 0"] cuMemAddressReserve: - [OutScalar, ptr] cuMemCreate: @@ -311,10 +311,10 @@ meta_parameters: - [InScalar, location] - [OutScalar, flags] cuMemExportToShareableHandle: - - [OutLTTng, shareableHandle, lttng_ust_field_variable_length_blob, shareableHandle_val, shareableHandle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] + - [OutLTTng, shareableHandle, lttng_ust_field_variable_length_blob, shareableHandle_val, shareableHandle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] cuMemImportFromShareableHandle: - [OutScalar, handle] - - [InLTTng, osHandle, lttng_ust_field_variable_length_blob, osHandle_val, osHandle, size_t, "shHandleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] + - [InLTTng, osHandle, lttng_ust_field_variable_length_blob, osHandle_val, osHandle, size_t, "shHandleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] cuMemGetAllocationGranularity: - [InScalar, prop] - [OutScalar, granularity] @@ -333,7 +333,7 @@ meta_parameters: attr == CU_MEMPOOL_ATTR_REUSE_ALLOW_INTERNAL_DEPENDENCIES ? sizeof(int) : \ attr == CU_MEMPOOL_ATTR_RELEASE_THRESHOLD ? sizeof(cuuint64_t) : \ attr == CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : \ - attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] + attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] cuMemPoolGetAttribute: - [OutLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == CU_MEMPOOL_ATTR_REUSE_FOLLOW_EVENT_DEPENDENCIES ? sizeof(int) : \ @@ -343,7 +343,7 @@ meta_parameters: attr == CU_MEMPOOL_ATTR_RESERVED_MEM_CURRENT ? sizeof(cuuint64_t) : \ attr == CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : \ attr == CU_MEMPOOL_ATTR_USED_MEM_CURRENT ? sizeof(cuuint64_t) : \ - attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] + attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] cuMemPoolSetAccess: - [InArray, map, count] cuMemPoolGetAccess: @@ -357,9 +357,9 @@ meta_parameters: cuMemAllocFromPoolAsync_ptsz: - [OutScalar, dptr] cuMemPoolExportToShareableHandle: - - [OutLTTng, handle_out, lttng_ust_field_variable_length_blob, handle_out_val, handle_out, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] + - [OutLTTng, handle_out, lttng_ust_field_variable_length_blob, handle_out_val, handle_out, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] cuMemPoolImportFromShareableHandle: - - [InLTTng, handle, lttng_ust_field_variable_length_blob, handle_val, handle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0", "application/octet-stream"] + - [InLTTng, handle, lttng_ust_field_variable_length_blob, handle_val, handle, size_t, "handleType == CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR ? sizeof(int) : 0"] - [OutScalar, pool_out] cuMemPoolExportPointer: - [OutScalar, shareData_out] @@ -393,14 +393,14 @@ meta_parameters: attribute == CU_POINTER_ATTRIBUTE_MEMPOOL_HANDLE ? sizeof(CUmemoryPool) : \ attribute == CU_POINTER_ATTRIBUTE_MAPPING_SIZE ? sizeof(size_t) : \ attribute == CU_POINTER_ATTRIBUTE_MAPPING_BASE_ADDR ? sizeof(void *) : \ - attribute == CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID ? sizeof(unsigned long long) : 0", "application/octet-stream"] + attribute == CU_POINTER_ATTRIBUTE_MEMORY_BLOCK_ID ? sizeof(unsigned long long) : 0"] cuMemRangeGetAttribute: - [OutArray, data, dataSize] cuMemRangeGetAttributes: - [InArray, attributes, numAttributes] - [InArray, dataSizes, numAttributes] cuPointerSetAttribute: - - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "attribute == CU_POINTER_ATTRIBUTE_SYNC_MEMOPS ? sizeof(uint8_t) : 0", "application/octet-stream"] + - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "attribute == CU_POINTER_ATTRIBUTE_SYNC_MEMOPS ? sizeof(uint8_t) : 0"] cuPointerGetAttributes: - [InArray, attributes, numAttributes] - [OutArray, data, numAttributes] @@ -630,11 +630,11 @@ meta_parameters: attr == CU_GRAPH_MEM_ATTR_USED_MEM_CURRENT ? sizeof(cuuint64_t) : \ attr == CU_GRAPH_MEM_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : \ attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_CURRENT ? sizeof(cuuint64_t) : \ - attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] + attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] cuDeviceSetGraphMemAttribute: - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == CU_GRAPH_MEM_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : \ - attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0", "application/octet-stream"] + attr == CU_GRAPH_MEM_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] cuGraphClone: - [OutScalar, phGraphClone] cuGraphNodeFindInClone: diff --git a/backends/hip/hip_meta_parameters.yaml b/backends/hip/hip_meta_parameters.yaml index c2887b29e..43686c706 100644 --- a/backends/hip/hip_meta_parameters.yaml +++ b/backends/hip/hip_meta_parameters.yaml @@ -110,7 +110,7 @@ meta_parameters: attribute == HIP_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES ? 0 : \ attribute == HIP_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE ? 0 : \ attribute == HIP_POINTER_ATTRIBUTE_ACCESS_FLAGS ? sizeof(hipMemAccessFlags) : \ - attribute == HIP_POINTER_ATTRIBUTE_MEMPOOL_HANDLE ? 0 : 0", "application/octet-stream"] + attribute == HIP_POINTER_ATTRIBUTE_MEMPOOL_HANDLE ? 0 : 0"] hipImportExternalSemaphore: - [InScalar, semHandleDesc] - [OutScalar, extSem_out] @@ -154,7 +154,7 @@ meta_parameters: attr == hipMemPoolAttrReservedMemCurrent ? 0 : \ attr == hipMemPoolAttrReservedMemHigh ? 0 : \ attr == hipMemPoolAttrUsedMemCurrent ? 0 : \ - attr == hipMemPoolAttrUsedMemHigh ? 0 : 0", "application/octet-stream"] + attr == hipMemPoolAttrUsedMemHigh ? 0 : 0"] hipMemPoolGetAttribute: - [OutLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == hipMemPoolReuseFollowEventDependencies ? sizeof(int) : \ @@ -164,7 +164,7 @@ meta_parameters: attr == hipMemPoolAttrReservedMemCurrent ? 0 : \ attr == hipMemPoolAttrReservedMemHigh ? 0 : \ attr == hipMemPoolAttrUsedMemCurrent ? 0 : \ - attr == hipMemPoolAttrUsedMemHigh ? 0 : 0", "application/octet-stream"] + attr == hipMemPoolAttrUsedMemHigh ? 0 : 0"] hipMemPoolSetAccess: - [InArray, desc_list, count] hipMemPoolGetAccess: @@ -177,10 +177,10 @@ meta_parameters: - [OutScalar, dev_ptr] hipMemPoolExportToShareableHandle: - [OutLTTng, shared_handle, lttng_ust_field_variable_length_blob, shared_handle_val, shared_handle, size_t, "\ - handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] + handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] hipMemPoolImportFromShareableHandle: - [InLTTng, shared_handle, lttng_ust_field_variable_length_blob, shared_handle_val, shared_handle, size_t, "\ - handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] + handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] - [OutScalar, mem_pool] hipMemPoolExportPointer: - [OutScalar, export_data] @@ -520,11 +520,11 @@ meta_parameters: attr == hipGraphMemAttrUsedMemCurrent ? sizeof(uint64_t) : \ attr == hipGraphMemAttrUsedMemHigh ? sizeof(uint64_t) : \ attr == hipGraphMemAttrReservedMemCurrent ? sizeof(uint64_t) : \ - attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0", "application/octet-stream"] + attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0"] hipDeviceSetGraphMemAttribute: - [InLTTng, value, lttng_ust_field_variable_length_blob, value_val, value, size_t, "\ attr == hipGraphMemAttrUsedMemHigh ? sizeof(uint64_t) : \ - attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0", "application/octet-stream"] + attr == hipGraphMemAttrReservedMemHigh ? sizeof(uint64_t) : 0"] hipUserObjectCreate: - [OutScalar, object_out] hipMemAddressReserve: @@ -534,7 +534,7 @@ meta_parameters: - [OutScalar, handle] hipMemExportToShareableHandle: - [OutLTTng, shareableHandle, lttng_ust_field_variable_length_blob, shareableHandle_val, shareableHandle, size_t, "\ - handleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] + handleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] hipMemGetAccess: - [InScalar, location] - [OutScalar, flags] @@ -545,7 +545,7 @@ meta_parameters: - [OutScalar, prop] hipMemImportFromShareableHandle: - [InLTTng, osHandle, lttng_ust_field_variable_length_blob, osHandle_val, osHandle, size_t, "\ - shHandleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0", "application/octet-stream"] + shHandleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] - [OutScalar, handle] hipMemMapArrayAsync: - [InScalar, mapInfoList] diff --git a/backends/opencl/gen_babeltrace_cl_model.rb b/backends/opencl/gen_babeltrace_cl_model.rb index 46b7189b8..d31949e93 100644 --- a/backends/opencl/gen_babeltrace_cl_model.rb +++ b/backends/opencl/gen_babeltrace_cl_model.rb @@ -59,6 +59,7 @@ def parse_field(field) when 'lttng_ust_field_variable_length_blob' d[:field_class][:type] = 'blob_dynamic' d[:field_class][:length_field_location] = payload_length_field_location(field['name']) + d[:field_class][:media_type] = LTTng::TracepointField.media_type(field['type']) d[:metadata] = { be_class: cl_to_class(field['type']) } if field['structure'] when 'ctf_array' d[:field_class][:type] = 'array_static' diff --git a/backends/opencl/opencl_events.yaml b/backends/opencl/opencl_events.yaml index a87a6ae4b..968947114 100644 --- a/backends/opencl/opencl_events.yaml +++ b/backends/opencl/opencl_events.yaml @@ -109,7 +109,7 @@ lttng_ust_opencl_dump: - [ctf_integer, uint64_t, enqueue_counter, enqueue_counter] - [ctf_integer, cl_uint, arg_index, arg_index] - [ctf_integer, size_t, arg_size, arg_size] - - [lttng_ust_field_variable_length_blob, arg_value, arg_value, size_t, "arg_value == NULL ? 0 : arg_size", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, arg_value, arg_value, size_t, "arg_value == NULL ? 0 : arg_size"] - name: svmptr_dump_event args: - [uint64_t, enqueue_counter] diff --git a/backends/opencl/opencl_model.rb b/backends/opencl/opencl_model.rb index af35071d9..15f605d14 100644 --- a/backends/opencl/opencl_model.rb +++ b/backends/opencl/opencl_model.rb @@ -394,11 +394,8 @@ def lttng_array_type_broker(type, name, size, stype = nil) when *CL_FLOAT_SCALARS lttng_type = ["ctf_#{lttng_arr_type}_hex", CL_FLOAT_SCALARS_MAP[type]] when *CL_STRUCTS, 'void' - # Raw bytes rather than a run of numbers, so a blob. Its slots are not the - # ctf_* array ones: no element type, and a media type at the end. return ['lttng_ust_field_variable_length_blob', name + '_vals', expr, - *blob_length_args(stype, name, size), - LTTng::TracepointField::DEFAULT_MEDIA_TYPE] + *blob_length_args(stype, name, size)] else raise "Unknown Type: #{type.inspect} for #{name} in #{@command.prototype.name}!" end @@ -440,7 +437,7 @@ def initialize(command, name, nocheck: false) @lttng_in_type = ['ctf_float', type, name + '_val', nocheck ? "*#{name}" : "#{name} == NULL ? 0 : *#{name}"] when *CL_STRUCTS @lttng_in_type = ['lttng_ust_field_variable_length_blob', name + '_val', "(uint8_t *)#{name}", 'size_t', - "#{name} == NULL ? 0 : sizeof(#{type})", LTTng::TracepointField::DEFAULT_MEDIA_TYPE] + "#{name} == NULL ? 0 : sizeof(#{type})"] else raise "Unknown Type: #{type.inspect}!" end @@ -734,8 +731,7 @@ def void_parameters? buffer_create_info = InMetaParameter.new(OPENCL_COMMANDS['clCreateSubBuffer'], 'buffer_create_info') buffer_create_info.instance_variable_set(:@lttng_in_type, ['lttng_ust_field_variable_length_blob', 'buffer_create_info_vals', 'buffer_create_info', 'size_t', - 'buffer_create_info == NULL ? 0 : (buffer_create_type == CL_BUFFER_CREATE_TYPE_REGION ? sizeof(cl_buffer_region) : 0)', - LTTng::TracepointField::DEFAULT_MEDIA_TYPE]) + 'buffer_create_info == NULL ? 0 : (buffer_create_type == CL_BUFFER_CREATE_TYPE_REGION ? sizeof(cl_buffer_region) : 0)']) OPENCL_COMMANDS['clCreateSubBuffer'].meta_parameters.push buffer_create_info diff --git a/backends/opencl/opencl_wrapper_events.yaml b/backends/opencl/opencl_wrapper_events.yaml index c166320bd..4fa00f8ef 100644 --- a/backends/opencl/opencl_wrapper_events.yaml +++ b/backends/opencl/opencl_wrapper_events.yaml @@ -33,7 +33,7 @@ lttng_ust_opencl: - [ctf_integer, size_t, cb, cb] - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - [ctf_string, errinfo_val, errinfo] - - [lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)"] - name: clCreateContextFromType_callback args: - ["const char *", errinfo] @@ -46,7 +46,7 @@ lttng_ust_opencl: - [ctf_integer, size_t, cb, cb] - [ctf_integer_hex, uintptr_t, user_data, "(uintptr_t)user_data"] - [ctf_string, errinfo_val, errinfo] - - [lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, private_info_vals, private_info, size_t, "(private_info ? cb : 0)"] - name: clSetMemObjectDestructorCallback_callback args: - [cl_mem, memobj] diff --git a/backends/ze/gen_babeltrace_ze_model.rb b/backends/ze/gen_babeltrace_ze_model.rb index acf978411..7a13d1a3d 100644 --- a/backends/ze/gen_babeltrace_ze_model.rb +++ b/backends/ze/gen_babeltrace_ze_model.rb @@ -10,7 +10,8 @@ def gen_struct_event_bt_model(registry, provider, struct) address = LTTng::TracepointField.new('ctf_integer_hex', 'uintptr_t', 'p', 'p') bytes = LTTng::TracepointField.new('lttng_ust_field_variable_length_blob', 'p_val', 'p', 'size_t', - UNREAD_LENGTH, LTTng::TracepointField::DEFAULT_MEDIA_TYPE) + UNREAD_LENGTH) + bytes.blob_type = struct gen_bt_event(registry, provider, struct, [['ctf_integer_hex', "#{struct} *", 'p', address], diff --git a/backends/ze/ze_events.yaml b/backends/ze/ze_events.yaml index 58f25240b..eac2a9d8d 100644 --- a/backends/ze/ze_events.yaml +++ b/backends/ze/ze_events.yaml @@ -8,7 +8,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer, uint32_t, deviceIdx, "deviceIdx"] - - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(zes_device_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(zes_device_properties_t)"] - name: engineProperties args: - [zes_device_handle_t, hDevice] @@ -17,7 +17,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hEngines, "(uintptr_t)hEngines"] - - [lttng_ust_field_variable_length_blob, pEngineProperties_val, pEngineProperties, size_t, "sizeof(zes_engine_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pEngineProperties_val, pEngineProperties, size_t, "sizeof(zes_engine_properties_t)"] - name: engineStats args: - [zes_device_handle_t, hDevice] @@ -26,7 +26,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hEngines, "(uintptr_t)hEngines"] - - [lttng_ust_field_variable_length_blob, pEngineStats_val, pEngineStats, size_t, "sizeof(zes_engine_stats_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pEngineStats_val, pEngineStats, size_t, "sizeof(zes_engine_stats_t)"] - name: powerProperties args: - [zes_device_handle_t, hDevice] @@ -35,7 +35,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hPowers, "(uintptr_t)hPowers"] - - [lttng_ust_field_variable_length_blob, pPowerProperties_val, pPowerProperties, size_t, "sizeof(zes_power_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pPowerProperties_val, pPowerProperties, size_t, "sizeof(zes_power_properties_t)"] - name: gpu_energy args: - [zes_device_handle_t, hDevice] @@ -46,7 +46,7 @@ lttng_ust_ze_sampling: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hPowers, "(uintptr_t)hPowers"] - [ctf_integer, uint32_t, domainIdx, "domainIdx"] - - [lttng_ust_field_variable_length_blob, pEnergyCounter_val, pEnergyCounter, size_t, "sizeof(zes_power_energy_counter_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pEnergyCounter_val, pEnergyCounter, size_t, "sizeof(zes_power_energy_counter_t)"] - name: freqProperties args: - [zes_device_handle_t, hDevice] @@ -55,7 +55,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFrequency, "(uintptr_t)hFrequency"] - - [lttng_ust_field_variable_length_blob, pFreqProperties_val, pFreqProperties, size_t, "sizeof(zes_freq_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pFreqProperties_val, pFreqProperties, size_t, "sizeof(zes_freq_properties_t)"] - name: gpu_frequency args: - [zes_device_handle_t, hDevice] @@ -66,7 +66,7 @@ lttng_ust_ze_sampling: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFrequency, "(uintptr_t)hFrequency"] - [ctf_integer, uint32_t, domainIdx, "domainIdx"] - - [lttng_ust_field_variable_length_blob, pFreqState_val, pFreqState, size_t, "sizeof(zes_freq_state_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pFreqState_val, pFreqState, size_t, "sizeof(zes_freq_state_t)"] - name: fabricPortProperties args: - [zes_device_handle_t, hDevice] @@ -75,7 +75,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFabricPort, "(uintptr_t)hFabricPort"] - - [lttng_ust_field_variable_length_blob, pFabricPortProperties_val, pFabricPortProperties, size_t, "sizeof(zes_fabric_port_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pFabricPortProperties_val, pFabricPortProperties, size_t, "sizeof(zes_fabric_port_properties_t)"] - name: fabricPort args: - [zes_device_handle_t, hDevice] @@ -85,8 +85,8 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hFabricPort, "(uintptr_t)hFabricPort"] - - [lttng_ust_field_variable_length_blob, pFabricPortState_val, pFabricPortState, size_t, "sizeof(zes_fabric_port_state_t)", "application/octet-stream"] - - [lttng_ust_field_variable_length_blob, pFabricPortThroughput_val, pFabricPortThroughput, size_t, "sizeof(zes_fabric_port_throughput_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pFabricPortState_val, pFabricPortState, size_t, "sizeof(zes_fabric_port_state_t)"] + - [lttng_ust_field_variable_length_blob, pFabricPortThroughput_val, pFabricPortThroughput, size_t, "sizeof(zes_fabric_port_throughput_t)"] - name: memoryProperties args: - [zes_device_handle_t, hDevice] @@ -95,7 +95,7 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hMemModule, "(uintptr_t)hMemModule"] - - [lttng_ust_field_variable_length_blob, pMemModuleProperties_val, pMemModuleProperties, size_t, "sizeof(zes_mem_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pMemModuleProperties_val, pMemModuleProperties, size_t, "sizeof(zes_mem_properties_t)"] - name: memStats args: - [zes_device_handle_t, hDevice] @@ -105,8 +105,8 @@ lttng_ust_ze_sampling: fields: - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hMemModule, "(uintptr_t)hMemModule"] - - [lttng_ust_field_variable_length_blob, pMemState_val, pMemState, size_t, "sizeof(zes_mem_state_t)", "application/octet-stream"] - - [lttng_ust_field_variable_length_blob, pMemBandwidth_val, pMemBandwidth, size_t, "sizeof(zes_mem_bandwidth_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pMemState_val, pMemState, size_t, "sizeof(zes_mem_state_t)"] + - [lttng_ust_field_variable_length_blob, pMemBandwidth_val, pMemBandwidth, size_t, "sizeof(zes_mem_bandwidth_t)"] lttng_ust_ze_profiling: events: - name: event_profiling @@ -139,7 +139,7 @@ lttng_ust_ze_properties: - [ze_driver_properties_t *, pDriverProperties] fields: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - - [lttng_ust_field_variable_length_blob, pDriverProperties_val, pDriverProperties, size_t, "sizeof(ze_driver_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pDriverProperties_val, pDriverProperties, size_t, "sizeof(ze_driver_properties_t)"] - name: device args: - [ze_driver_handle_t, hDriver] @@ -148,7 +148,7 @@ lttng_ust_ze_properties: fields: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)"] - name: subdevice args: - [ze_driver_handle_t, hDriver] @@ -159,7 +159,7 @@ lttng_ust_ze_properties: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer_hex, uintptr_t, hSubDevice, "(uintptr_t)hSubDevice"] - - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pDeviceProperties_val, pDeviceProperties, size_t, "sizeof(ze_device_properties_t)"] - name: command_queue_group args: - [ze_driver_handle_t, hDriver] @@ -170,7 +170,7 @@ lttng_ust_ze_properties: - [ctf_integer_hex, uintptr_t, hDriver, "(uintptr_t)hDriver"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - [ctf_integer, uint32_t, pCount, pCount] - - [lttng_ust_field_variable_length_blob, pGroupProperties_vals, pGroupProperties, size_t, "pCount * sizeof(ze_command_queue_group_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pGroupProperties_vals, pGroupProperties, size_t, "pCount * sizeof(ze_command_queue_group_properties_t)"] - name: device_timer args: - [ze_device_handle_t, hDevice] @@ -189,7 +189,7 @@ lttng_ust_ze_properties: fields: - [ctf_integer_hex, uintptr_t, hContext, "(uintptr_t)hContext"] - [ctf_integer_hex, uintptr_t, ptr, "(uintptr_t)ptr"] - - [lttng_ust_field_variable_length_blob, pMemAllocProperties_val, pMemAllocProperties, size_t, "sizeof(ze_memory_allocation_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pMemAllocProperties_val, pMemAllocProperties, size_t, "sizeof(ze_memory_allocation_properties_t)"] - [ctf_integer_hex, uintptr_t, hDevice, "(uintptr_t)hDevice"] - name: memory_info_range args: @@ -208,7 +208,7 @@ lttng_ust_ze_properties: - [ze_kernel_properties_t *, pKernelProperties] fields: - [ctf_integer_hex, uintptr_t, hKernel, "(uintptr_t)hKernel"] - - [lttng_ust_field_variable_length_blob, pKernelProperties_val, pKernelProperties, size_t, "sizeof(ze_kernel_properties_t)", "application/octet-stream"] + - [lttng_ust_field_variable_length_blob, pKernelProperties_val, pKernelProperties, size_t, "sizeof(ze_kernel_properties_t)"] lttng_ust_ze_build: events: - name: log diff --git a/utils/LTTng.rb b/utils/LTTng.rb index 40aaf74de..3702d99f6 100644 --- a/utils/LTTng.rb +++ b/utils/LTTng.rb @@ -76,12 +76,15 @@ class TracepointField ctf_sequence_network_hex: %i[type name expression length_type length], ctf_sequence_text: %i[type name expression length_type length], ctf_string: %i[name expression], - lttng_ust_field_fixed_length_blob: %i[name expression length media_type], - lttng_ust_field_variable_length_blob: %i[name expression length_type length media_type], + lttng_ust_field_fixed_length_blob: %i[name expression length], + lttng_ust_field_variable_length_blob: %i[name expression length_type length], } - # IANA media type for arbitrary binary struct/buffer data recorded as a blob. + # `void *` is encoded as a blob. Put some media type for those. DEFAULT_MEDIA_TYPE = 'application/octet-stream'.freeze - attr_accessor :macro, :expression, :type, :provider_name, :enum_name, :length, :length_type, :cast, :media_type + # Other blobs have their type as media type, prefixed by BLOB_ARCH. + BLOB_ARCH = 'x86-64' + attr_accessor :macro, :expression, :type, :provider_name, :enum_name, :length, :length_type, :cast, + :blob_type attr_reader :name def initialize(*args) @@ -103,9 +106,24 @@ def initialize(*args) @expression = m[2] end + def self.media_type(c_type) + t = c_type.to_s.sub(/\Aconst /, '').delete('*').strip + t.empty? || t == 'void' ? DEFAULT_MEDIA_TYPE : "#{BLOB_ARCH}/#{t}" + end + + def media_type + TracepointField.media_type(@blob_type) + end + + BLOB_MACROS = FIELDS.keys.grep(/_blob\z/).freeze + + def blob? + BLOB_MACROS.include?(@macro) + end + def call_string expr = @cast ? "(#{@cast})(#{@expression})" : @expression - media_type = "\"#{@media_type || DEFAULT_MEDIA_TYPE}\"" + media_type = "\"#{self.media_type}\"" args = case @macro when :lttng_ust_field_fixed_length_blob @@ -140,6 +158,13 @@ def self.print_enum(namespace, en) EOF end + # The C type of the argument a field records. A field is named after its + # argument, plus a `_val`/`_vals` suffix when it reads through a pointer. + def self.argument_type(args, field_name) + name = field_name.sub(/_vals?\z/, '') + args.find { |_type, arg_name| arg_name == name }&.first + end + def self.print_tracepoint(namespace, tp, phase = nil, suffix: nil) puts <<~EOF TRACEPOINT_EVENT( @@ -153,7 +178,11 @@ def self.print_tracepoint(namespace, tp, phase = nil, suffix: nil) ), TP_FIELDS( EOF - fields = tp[phase || 'fields'].to_a.collect { |field| TracepointField.new(*field).call_string } + fields = tp[phase || 'fields'].to_a.collect do |field| + f = TracepointField.new(*field) + f.blob_type = argument_type(tp['args'], f.name.to_s) if f.blob? + f.call_string + end puts indented(fields) unless fields.empty? puts <<~EOF ) diff --git a/utils/gen_babeltrace_model_helper.rb b/utils/gen_babeltrace_model_helper.rb index ea00c6dd9..63a6cc368 100644 --- a/utils/gen_babeltrace_model_helper.rb +++ b/utils/gen_babeltrace_model_helper.rb @@ -53,7 +53,8 @@ def get_extra_fields_types_name(event) event['fields'].collect do |field| lttng = LTTng::TracepointField.new(*field) name = lttng.name.to_s - type = event['args'].find { |_t, n| n == name || n == name.gsub(/_vals?\z/, '') }[0] + type = LTTng.argument_type(event['args'], name) + lttng.blob_type = type field_types_name(lttng.macro.to_s, type, name, lttng) end.flatten(1) end @@ -124,7 +125,7 @@ def gen_bt_field_model(registry, lttng_name, type, name, lttng) field[:type] = 'blob_dynamic' field[:length_field_location] = payload_length_field_location(name) end - field[:media_type] = lttng.media_type if lttng.media_type + field[:media_type] = lttng.media_type name_packed_struct(registry, member, type) else raise "unsupported lttng type: #{lttng.inspect}" diff --git a/utils/gen_probe_base.rb b/utils/gen_probe_base.rb index 121785772..1da1328bb 100644 --- a/utils/gen_probe_base.rb +++ b/utils/gen_probe_base.rb @@ -130,18 +130,13 @@ def print_struct_tracepoint_provider(provider, structs, include:) end def print_struct_tracepoint(provider, t) - puts <<~EOF - TRACEPOINT_EVENT( - #{provider}, - #{t}, - TP_ARGS( - #{t} *, p - ), - TP_FIELDS( - ctf_integer_hex(uintptr_t, p, (uintptr_t)(p)) - lttng_ust_field_variable_length_blob(p_val, p, size_t, (p ? sizeof(#{t}) : 0), "application/octet-stream") - ) - ) - - EOF + LTTng.print_tracepoint(provider, { + 'name' => t, + 'args' => [["#{t} *", 'p']], + 'fields' => [ + ['ctf_integer_hex', 'uintptr_t', 'p', '(uintptr_t)p'], + ['lttng_ust_field_variable_length_blob', 'p_val', 'p', 'size_t', + "(p ? sizeof(#{t}) : 0)"], + ], + }) end diff --git a/utils/meta_parameters.rb b/utils/meta_parameters.rb index 4e7f597d6..59b2b8a97 100644 --- a/utils/meta_parameters.rb +++ b/utils/meta_parameters.rb @@ -347,24 +347,31 @@ class OutArrayByRef < ArrayByRefMetaParameter prepend Out end -class OutLTTng < MetaParameter - prepend Out - +# A meta-parameter whose lttng field is given literally, slot by slot: +# +# - [OutScalar, pStr] # a rule builds the field +# - [OutLTTng, handle, lttng_ust_field_variable_length_blob, +# handle_val, handle, size_t, +# "handleType == CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD ? sizeof(int) : 0"] +# +# The length is a conditional on another argument (`handleType`), so no rule +# can compute it and the backend spells the row out. The bytes are still the +# parameter's own, so `blob_type` comes from the declaration, not the row. +class LTTngMetaParameter < MetaParameter def initialize(command, name, *args) - raise "Invalid parameter: #{name} for #{command.name}!" unless command[name] + decl = command[name] + raise "Invalid parameter: #{name} for #{command.name}!" unless decl super(command, name) @lttng_type = LTTng::TracepointField.new(*args) + @lttng_type.blob_type = decl.type.to_s if @lttng_type.blob? end end -class InLTTng < MetaParameter - prepend In - - def initialize(command, name, *args) - raise "Invalid parameter: #{name} for #{command.name}!" unless command[name] +class OutLTTng < LTTngMetaParameter + prepend Out +end - super(command, name) - @lttng_type = LTTng::TracepointField.new(*args) - end +class InLTTng < LTTngMetaParameter + prepend In end diff --git a/utils/yaml_ast_lttng.rb b/utils/yaml_ast_lttng.rb index b10d672cf..5305b6068 100644 --- a/utils/yaml_ast_lttng.rb +++ b/utils/yaml_ast_lttng.rb @@ -58,6 +58,7 @@ def lttng_type(_type_classes) ev.macro = :lttng_ust_field_fixed_length_blob ev.type = :uint8_t ev.length = "sizeof(struct #{name})" + ev.blob_type = "struct #{name}" ev end @@ -72,6 +73,7 @@ def lttng_type(_type_classes) ev.macro = :lttng_ust_field_fixed_length_blob ev.type = :uint8_t ev.length = "sizeof(union #{name})" + ev.blob_type = "union #{name}" ev end end @@ -132,6 +134,7 @@ def lttng_type(type_classes) ev.macro = :lttng_ust_field_fixed_length_blob ev.type = :uint8_t ev.length = "sizeof(#{name})" + ev.blob_type = name else super end @@ -194,6 +197,7 @@ def lttng_type(type_classes, length: nil, length_type: nil) ev.type = :uint8_t ev.length = "(#{ev.length}) * sizeof(#{type.name})" ev.length_type = 'size_t' + ev.blob_type = type.name else super(type_classes) end From fbbb15d09bf2071840eb06c2bc4e500dd98dfde5 Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Thu, 1 Oct 2026 20:57:19 +0000 Subject: [PATCH 09/10] Require the lttng-ust and babeltrace2 versions BLOB fields need THAPI records raw bytes as BLOB fields since the BLOB port, which bounds both halves of the round trip: lttng-ust 2.16 provides the lttng_ust_field_fixed_length_blob tracepoint macro that writes the field, and babeltrace2 2.1 the bt_field_class_blob_* API that metababel generates against to read it back. configure still asked for lttng-ust 2.10 and babeltrace2 2.0, the pre-BLOB floors. Both accept a stack that cannot build: configure passes and the build then fails on a name the headers have never heard of. Verified rather than assumed: lttng_ust_field_fixed_length_blob is absent from the 2.14 headers on this machine, and bt_field_class_blob_static_create appears first in babeltrace2 2.1.0 (absent in 2.0.6). --- configure.ac | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 79b06d7ae..ddba62179 100644 --- a/configure.ac +++ b/configure.ac @@ -125,8 +125,13 @@ AX_COMPARE_VERSION([$H2YAML_VERSION], [ge], [$H2YAML_MIN_VERSION], AC_MSG_ERROR([h2yaml version $H2YAML_VERSION is too old, need >= $H2YAML_MIN_VERSION])]) PKG_CHECK_MODULES([LIBFFI], [libffi >= 3.2]) -PKG_CHECK_MODULES([BABELTRACE2], [babeltrace2 >= 2.0]) -PKG_CHECK_MODULES([LTTNG_UST], [lttng-ust >= 2.10]) +# Both floors are the BLOB port. We write raw bytes as BLOB fields and read them +# back, so each half of the round trip needs a version that knows the field: +# lttng-ust 2.16 for the lttng_ust_field_fixed_length_blob tracepoint macro, and +# babeltrace2 2.1 for the bt_field_class_blob_* API that metababel generates +# against. Given an older one, the build fails on a name it has never heard of. +PKG_CHECK_MODULES([BABELTRACE2], [babeltrace2 >= 2.1]) +PKG_CHECK_MODULES([LTTNG_UST], [lttng-ust >= 2.16]) PKG_CHECK_MODULES([PROTOBUF], [protobuf >= 3.0]) AX_RUBY_EXTENSION([nokogiri], [yes]) From 161795c7743d0ee27cd662680e2914402ca34514 Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Thu, 1 Oct 2026 21:53:34 +0000 Subject: [PATCH 10/10] fix configure doc --- configure.ac | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index ddba62179..623b77b25 100644 --- a/configure.ac +++ b/configure.ac @@ -125,14 +125,10 @@ AX_COMPARE_VERSION([$H2YAML_VERSION], [ge], [$H2YAML_MIN_VERSION], AC_MSG_ERROR([h2yaml version $H2YAML_VERSION is too old, need >= $H2YAML_MIN_VERSION])]) PKG_CHECK_MODULES([LIBFFI], [libffi >= 3.2]) -# Both floors are the BLOB port. We write raw bytes as BLOB fields and read them -# back, so each half of the round trip needs a version that knows the field: -# lttng-ust 2.16 for the lttng_ust_field_fixed_length_blob tracepoint macro, and -# babeltrace2 2.1 for the bt_field_class_blob_* API that metababel generates -# against. Given an older one, the build fails on a name it has never heard of. +PKG_CHECK_MODULES([PROTOBUF], [protobuf >= 3.0]) +# For blob support PKG_CHECK_MODULES([BABELTRACE2], [babeltrace2 >= 2.1]) PKG_CHECK_MODULES([LTTNG_UST], [lttng-ust >= 2.16]) -PKG_CHECK_MODULES([PROTOBUF], [protobuf >= 3.0]) AX_RUBY_EXTENSION([nokogiri], [yes]) AX_RUBY_EXTENSION([babeltrace2], [yes])