diff --git a/.github/actions/setup-thapi/action.yml b/.github/actions/setup-thapi/action.yml index b0680b167..c0cf7da91 100644 --- a/.github/actions/setup-thapi/action.yml +++ b/.github/actions/setup-thapi/action.yml @@ -42,11 +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 - # 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 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: | @@ -70,10 +76,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 +86,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 +96,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/backends/cuda/cuda_events.yaml b/backends/cuda/cuda_events.yaml index 6d0867a8e..ca47a8c43 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" ] - - [ ctf_sequence_text, uint8_t, kernelParam_val, "(uint8_t *)kernelParam", size_t, "kernelParam ? argSize : 0" ] + - [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"] 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 ] - - [ ctf_sequence_text, uint8_t, pExportTableId_val, pExportTableId, size_t, "sizeof(CUuuid)" ] + - [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)"] 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 ] - - [ ctf_sequence_text, uint8_t, uuid, uuid, size_t, "sizeof(CUuuid)" ] + - [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)"] diff --git a/backends/cuda/cuda_meta_parameters.yaml b/backends/cuda/cuda_meta_parameters.yaml index d2f083804..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, 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"] 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"] 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"] cuMemGetAllocationGranularity: - [InScalar, prop] - [OutScalar, granularity] @@ -327,7 +327,7 @@ 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) : \ @@ -335,7 +335,7 @@ meta_parameters: attr == CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH ? sizeof(cuuint64_t) : \ attr == CU_MEMPOOL_ATTR_USED_MEM_HIGH ? sizeof(cuuint64_t) : 0"] 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) : \ @@ -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"] 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"] - [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) : \ @@ -400,7 +400,7 @@ meta_parameters: - [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"] cuPointerGetAttributes: - [InArray, attributes, numAttributes] - [OutArray, data, numAttributes] @@ -626,13 +626,13 @@ 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"] 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"] cuGraphClone: diff --git a/backends/hip/hip_meta_parameters.yaml b/backends/hip/hip_meta_parameters.yaml index 41aacc6bf..43686c706 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) : \ @@ -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) : \ @@ -156,7 +156,7 @@ meta_parameters: attr == hipMemPoolAttrUsedMemCurrent ? 0 : \ attr == hipMemPoolAttrUsedMemHigh ? 0 : 0"] 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) : \ @@ -176,10 +176,10 @@ meta_parameters: hipMallocFromPoolAsync: - [OutScalar, dev_ptr] hipMemPoolExportToShareableHandle: - - [OutLTTng, shared_handle, ctf_sequence_text, uint8_t, shared_handle_val, shared_handle, size_t, "\ + - [OutLTTng, shared_handle, lttng_ust_field_variable_length_blob, shared_handle_val, shared_handle, size_t, "\ handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] hipMemPoolImportFromShareableHandle: - - [InLTTng, shared_handle, ctf_sequence_text, uint8_t, shared_handle_val, shared_handle, size_t, "\ + - [InLTTng, shared_handle, lttng_ust_field_variable_length_blob, shared_handle_val, shared_handle, size_t, "\ handle_type == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] - [OutScalar, mem_pool] hipMemPoolExportPointer: @@ -516,13 +516,13 @@ 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"] 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"] hipUserObjectCreate: @@ -533,7 +533,7 @@ meta_parameters: - [InScalar, prop] - [OutScalar, handle] hipMemExportToShareableHandle: - - [OutLTTng, shareableHandle, ctf_sequence_text, uint8_t, shareableHandle_val, shareableHandle, size_t, "\ + - [OutLTTng, shareableHandle, lttng_ust_field_variable_length_blob, shareableHandle_val, shareableHandle, size_t, "\ handleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] hipMemGetAccess: - [InScalar, location] @@ -544,7 +544,7 @@ meta_parameters: hipMemGetAllocationPropertiesFromHandle: - [OutScalar, prop] hipMemImportFromShareableHandle: - - [InLTTng, osHandle, ctf_sequence_text, uint8_t, osHandle_val, osHandle, size_t, "\ + - [InLTTng, osHandle, lttng_ust_field_variable_length_blob, osHandle_val, osHandle, size_t, "\ shHandleType == hipMemHandleTypePosixFileDescriptor ? sizeof(int) : 0"] - [OutScalar, handle] hipMemMapArrayAsync: diff --git a/backends/opencl/gen_babeltrace_cl_model.rb b/backends/opencl/gen_babeltrace_cl_model.rb index 994f67aaf..d31949e93 100644 --- a/backends/opencl/gen_babeltrace_cl_model.rb +++ b/backends/opencl/gen_babeltrace_cl_model.rb @@ -53,9 +53,14 @@ 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 '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' d_field = parse_field({ 'lttng' => 'ctf_integer', 'type' => field['type'], 'pointer' => field['pointer'] }) @@ -65,13 +70,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'] @@ -99,7 +104,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..968947114 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 ] - - [ ctf_sequence_text, uint8_t, arg_value, arg_value, size_t, "arg_value == NULL ? 0 : arg_size" ] + - [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"] - 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_model.rb b/backends/opencl/opencl_model.rb index 85f03059c..15f605d14 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,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' - lttng_type = ["ctf_#{lttng_arr_type}_text", 'uint8_t'] + return ['lttng_ust_field_variable_length_blob', name + '_vals', expr, + *blob_length_args(stype, name, size)] else raise "Unknown Type: #{type.inspect} for #{name} in #{@command.prototype.name}!" end @@ -427,7 +436,7 @@ 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', + @lttng_in_type = ['lttng_ust_field_variable_length_blob', name + '_val', "(uint8_t *)#{name}", 'size_t', "#{name} == NULL ? 0 : sizeof(#{type})"] else raise "Unknown Type: #{type.inspect}!" @@ -721,7 +730,7 @@ 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', + ['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)']) 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..4fa00f8ef 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 ] - - [ ctf_sequence_text, uint8_t, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" ] + - [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)"] - 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 ] - - [ ctf_sequence_text, uint8_t, private_info_vals, private_info, size_t, "(private_info ? cb : 0)" ] + - [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)"] - 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"] diff --git a/backends/ze/gen_babeltrace_ze_model.rb b/backends/ze/gen_babeltrace_ze_model.rb index 61eaf0a7e..7a13d1a3d 100644 --- a/backends/ze/gen_babeltrace_ze_model.rb +++ b/backends/ze/gen_babeltrace_ze_model.rb @@ -1,19 +1,21 @@ 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) + bytes.blob_type = struct 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..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"] - - [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)"] - 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)"] - 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)"] - 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)"] - 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)"] - 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)"] - 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)"] - 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)"] - 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)"] + - [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"] - - [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)"] - 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)"] + - [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"] - - [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)"] - 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)"] - 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)"] - 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)"] - 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)"] - [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)"] lttng_ust_ze_build: events: - name: log diff --git a/configure.ac b/configure.ac index 661244ebd..623b77b25 100644 --- a/configure.ac +++ b/configure.ac @@ -125,13 +125,14 @@ 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]) 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]) 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..3702d99f6 100644 --- a/utils/LTTng.rb +++ b/utils/LTTng.rb @@ -76,8 +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], + lttng_ust_field_variable_length_blob: %i[name expression length_type length], } - attr_accessor :macro, :expression, :type, :provider_name, :enum_name, :length, :length_type, :cast + # `void *` is encoded as a blob. Put some media type for those. + DEFAULT_MEDIA_TYPE = 'application/octet-stream'.freeze + # 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) @@ -99,11 +106,34 @@ 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 - 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 = "\"#{self.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) @@ -128,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( @@ -141,7 +178,11 @@ 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 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/babeltrace_thapi.in b/utils/babeltrace_thapi.in index 3e3b187fb..828896c44 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 = [] @@ -130,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| @@ -234,7 +244,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..63a6cc368 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 @@ -48,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 @@ -63,6 +69,16 @@ 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, 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) +end + def gen_bt_field_model(registry, lttng_name, type, name, lttng) types_by_name = registry.types_by_name member = { name: name } @@ -89,23 +105,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' - field[:type] = 'string' - when 'ctf_sequence_text', 'ctf_array_text' + when 'ctf_string', 'ctf_sequence_text', 'ctf_array_text' + # Genuine text: char strings and char sequences/arrays. 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, 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 + name_packed_struct(registry, 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..1da1328bb 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) @@ -123,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)) - ctf_sequence_text(uint8_t, p_val, p, size_t, (p ? sizeof(#{t}) : 0)) - ) - ) - - 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 ba802dae9..59b2b8a97 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 @@ -156,8 +162,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) @@ -210,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}") @@ -291,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}") @@ -337,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}") @@ -354,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.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 461632864..5305b6068 100644 --- a/utils/yaml_ast_lttng.rb +++ b/utils/yaml_ast_lttng.rb @@ -55,9 +55,10 @@ 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.blob_type = "struct #{name}" ev end @@ -69,9 +70,10 @@ 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.blob_type = "union #{name}" ev end end @@ -129,9 +131,10 @@ 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})" + ev.blob_type = name else super end @@ -172,10 +175,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 @@ -189,12 +189,15 @@ 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" + # 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.length = "(#{ev.length}) * sizeof(#{type.name})" + ev.length_type = 'size_t' + ev.blob_type = type.name else super(type_classes) end